Comment formater une chaîne JSON en tant que table en utilisant jq?
Vient de commencer avec Bash scripting et est tombé sur jq pour travailler avec JSON.
J'ai besoin de transformer une chaîne JSON comme ci-dessous en une table pour la sortie dans le terminal.
[{
"name": "George",
"id": 12,
"email": "george@domain.com"
}, {
"name": "Jack",
"id": 18,
"email": "jack@domain.com"
}, {
"name": "Joe",
"id": 19,
"email": "joe@domain.com"
}]
Ce que je veux afficher dans le terminal:
ID Name
=================
12 George
18 Jack
19 Joe
Remarquez comment je ne veux pas afficher la propriété email pour chaque ligne, donc la commande jq devrait impliquer un filtrage. Ce qui suit me donne une liste simple de noms et d'identifiants:
list=$(echo "$data" | jq -r '.[] | .name, .id')
printf "$list"
Le problème avec cela est, Je ne peux pas l'afficher comme table. Je sais que jq a quelques options de formatage, mais pas aussi bonnes que les options que j'ai en utilisant printf
. Je pense que je veux obtenir ces valeurs dans un tableau que je peux ensuite parcourir moi-même pour faire le formatage...? Les choses que j'ai essayées me donnent des résultats variables, mais jamais ce que je veux vraiment.
Quelqu'un peut-il me diriger dans la bonne direction?
3 réponses
, Pourquoi pas quelque chose comme :
echo '[{
"name": "George",
"id": 12,
"email": "george@domain.com"
}, {
"name": "Jack",
"id": 18,
"email": "jack@domain.com"
}, {
"name": "Joe",
"id": 19,
"email": "joe@domain.com"
}]' | jq -r '.[] | "\(.id)\t\(.name)"'
Sortie
12 George
18 Jack
19 Joe
Edit 1: pour le formatage à grain fin, utilisez des outils tels que awk
echo '[{
"name": "George",
"id": 12,
"email": "george@domain.com"
}, {
"name": "Jack",
"id": 18,
"email": "jack@domain.com"
}, {
"name": "Joe",
"id": 19,
"email": "joe@domain.com"
}]' | 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"
Edit 2 : En réponse à
Il n'y a aucun moyen que je puisse obtenir une variable contenant un tableau directement de jq?
Pourquoi pas?
Un exemple peu impliqué (en fait modifié à partir du vôtre ) où l'email est changé en un tableau démontre ce
echo '[{
"name": "George",
"id": 20,
"email": [ "george@domain1.com" , "george@domain2.com" ]
}, {
"name": "Jack",
"id": 18,
"email": [ "jack@domain3.com" , "jack@domain5.com" ]
}, {
"name": "Joe",
"id": 19,
"email": [ "joe@domain.com" ]
}]' | jq -r '.[] | .email'
Sortie
[
"george@domain1.com",
"george@domain2.com"
]
[
"jack@domain3.com",
"jack@domain5.com"
]
[
"joe@domain.com"
]
L'utilisation du filtre @tsv
a beaucoup à recommander, principalement parce qu'il gère de nombreux "cas de bord" de manière standard:
.[] | [.id, .name] | @tsv
L'ajout des en-têtes peut se faire comme suit:
jq -r '["ID","NAME"], ["--","------"], (.[] | [.id, .name]) | @tsv'
Le résultat:
ID NAME
-- ------
12 George
18 Jack
19 Joe
Si les valeurs ne contiennent pas d'espaces, cela peut être utile:
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
Sortie
name value
==========
name1 value1
name2 value2