Как форматировать строку JSON в виде таблицы с помощью jq?
Просто начал с Bash скриптинга и наткнулся на jq, чтобы работать с JSON.
Мне нужно преобразовать строку JSON, как показано ниже, в таблицу для вывода в терминале.
[{
"name": "George",
"id": 12,
"email": "[email protected]"
}, {
"name": "Jack",
"id": 18,
"email": "[email protected]"
}, {
"name": "Joe",
"id": 19,
"email": "[email protected]"
}]
Что я хочу отображать в терминале:
ID Name
=================
12 George
18 Jack
19 Joe
Обратите внимание, что я не хочу отображать свойство электронной почты для каждой строки, поэтому команда jq должна включать некоторую фильтрацию. Следующее дает мне простой список имен и идентификаторов:
list=$(echo "$data" | jq -r '.[] | .name, .id')
printf "$list"
Проблема в том, что я не могу отображать его как таблицу. Я знаю, что jq имеет некоторые параметры форматирования, но не так хорош, как параметры, которые у меня есть при использовании printf
. Я думаю, что хочу получить эти значения в массиве, который затем я смогу прокрутить сам, чтобы сделать форматирование...? То, что я пробовал, дало мне разные результаты, но я никогда этого не делал.
Может ли кто-нибудь указать мне в правильном направлении?
Ответы
Ответ 1
Почему бы не что-то вроде:
echo '[{
"name": "George",
"id": 12,
"email": "[email protected]"
}, {
"name": "Jack",
"id": 18,
"email": "[email protected]"
}, {
"name": "Joe",
"id": 19,
"email": "[email protected]"
}]' | jq -r '.[] | "\(.id)\t\(.name)"'
Вывод
12 George
18 Jack
19 Joe
Изменить 1: для мелкозернистого форматирования используйте такие инструменты, как awk
echo '[{
"name": "George",
"id": 12,
"email": "[email protected]"
}, {
"name": "Jack",
"id": 18,
"email": "[email protected]"
}, {
"name": "Joe",
"id": 19,
"email": "[email protected]"
}]' | jq -r '.[] | [.id, .name] | @csv' | awk -v FS="," 'BEGIN{print "ID\tName";print "============"}{printf "%s\t%s%s",$1,$2,ORS}'
ID Name
============
12 "George"
18 "Jack"
19 "Joe"
Редактировать 2: В ответ на
Я не могу получить переменную, содержащую массив прямо из jq?
Почему нет?
Немного вовлеченный пример (фактически измененный от вашего), где электронная почта изменена на массив, демонстрирует это
echo '[{
"name": "George",
"id": 20,
"email": [ "[email protected]" , "[email protected]" ]
}, {
"name": "Jack",
"id": 18,
"email": [ "[email protected]" , "[email protected]" ]
}, {
"name": "Joe",
"id": 19,
"email": [ "[email protected]" ]
}]' | jq -r '.[] | .email'
Вывод
[
"[email protected]",
"[email protected]"
]
[
"[email protected]",
"[email protected]"
]
[
"[email protected]"
]
Ответ 2
Использование фильтра @tsv
может многое рекомендовать, главным образом потому, что он обрабатывает множество "краевых случаев" стандартным образом:
.[] | [.id, .name] | @tsv
Добавление заголовков можно сделать так:
jq -r '["ID","NAME"], ["--","------"], (.[] | [.id, .name]) | @tsv'
Результат:
ID NAME
-- ------
12 George
18 Jack
19 Joe
Ответ 3
Если значения не содержат пробелов, это может быть полезно:
read -r -a data <<<'name1 value1 name2 value2'
echo "name value"
echo "=========="
for ((i=0; i<${#data[@]}; i+=2)); do
echo ${data[$i]} ${data[$((i+1))]}
done
Вывод
name value
==========
name1 value1
name2 value2