Как манипулировать выводом jq, используя bash? - PullRequest
0 голосов
/ 12 сентября 2018

У меня есть следующий фрагмент кода jq:

https://jqplay.org/s/QzOttRHoz1

Я хочу зациклить каждый элемент массива результатов, используя bash, например, показ псевдокода:

#!/bin/bash
foreach result
  print "My name is {name}, I'm {age} years old"
  print "--"

Результатом будет:

My name is A, I'm 1 years old.
---
My name is B, I'm 2 years old.
---
My name is C, I'm 3 years old.
---

Конечно, это тривиальный пример, просто для пояснения, что моя цель - манипулировать каждым массивом из результата jq по отдельности.

Любые предложенияо том, как записать псевдокод в допустимые операторы bash?

Ответы [ 3 ]

0 голосов
/ 12 сентября 2018

Я написал простой скрипт для достижения того, что вам нужно:

Мой файл Json test.json, который похож на ваш фрагмент:

{
    "Names": [
        { "Name": "A", "Age": "1" },
        { "Name": "B", "Age": "2" },
        { "Name": "C", "Age": "3" }
    ]
}

Мой сценарий:

#!/bin/bash
for i in $(cat test.json | jq -r '.Names[] | @base64'); do
    _jq() {
     echo ${i} | base64 --decode | jq -r ${1}
    }
   echo "My Name is $(_jq '.Name'), I'm $(_jq '.Age') years old"
done
0 голосов
/ 12 сентября 2018

Обратите внимание, что foreach .Names[] as $name ([];[];$name | .Name, .Age ) можно упростить до:

.Names[] | ( .Name, .Age )

или даже в этом конкретном случае:

.Names[][]

или в этом отношении:

.[][][]

Важным моментом, однако, является то, что foreach не требуется для достижения простой итерации.

0 голосов
/ 12 сентября 2018

Сохранение json:

{
    "Names": [
        { "Name": "A", "Age": "1" },
        { "Name": "B", "Age": "2" },
        { "Name": "C", "Age": "3" }
    ]
}

как /tmp/input.txt Я могу запустить:

</tmp/input.txt jq --raw-output 'foreach .Names[] as $name ([];[];$name | .Name, .Age )' \
| while read -r name && read -r age; do 
      printf "My name is %s, I'm %d years old.\n" "$name" "$age"; 
      printf -- "--\n";
done

--raw-output с | .Name, .Age просто печатает две строки в.Член массива имен, один с именем, а другой с возрастом.Затем я читаю две строки за раз с while read && read и использую их для их циклического просмотра.

Если вы предпочитаете:

["A","1"]
["B","2"]
["C","3"]

, то это печально, лучше всего написатьполный синтаксический анализатор, который будет учитывать строки типа "\"".В любом случае, вы можете:

</tmp/input2.txt sed 's/^\[//;s/\]$//;' \
| while IFS=, read name age; do 
       name=${name%\"}; 
       name=${name#\"};   
       age=${age%\"};
       age=${age#\"};
       printf "My name is %s, I'm %d years old.\n" "$name" "$age";
       printf -- "--\n";
done

Первый сед убрал начальные и включающие [ и ] в каждой строке.Затем я читаю две строки, разделенные , (поэтому переменные типа "a,b","c,d" будут прочитаны неправильно).Затем эти две струны лишаются ведущей и заключающей ".Затем для вывода результата используется обычный printf.

...