web-dev-qa-db-fra.com

jq: clé d'impression et valeur pour chaque entrée d'un objet

Comment puis-je utiliser jq pour prendre json comme ceci:

{
  "Host1": { "ip": "10.1.2.3" },
  "Host2": { "ip": "10.1.2.2" },
  "Host3": { "ip": "10.1.18.1" }
}

et générer cette sortie:

Host1, 10.1.2.3
Host2, 10.1.2.2
Host3, 10.1.18.1

La mise en forme ne m'intéresse pas, je ne sais pas comment accéder au nom et à la valeur de la clé.

45
Jeff Tang

Pour obtenir les clés de niveau supérieur sous forme de flux, vous pouvez utiliser les clés []. Donc, une solution à votre problème particulier serait:

jq -r 'keys[] as $k | "\($k), \(.[$k] | .ip)"' 

keys produit les noms de clé dans un ordre trié; si vous les voulez dans l'ordre d'origine, utilisez keys_unsorted.

Une autre alternative, qui produit les clés dans l'ordre d'origine, est la suivante:

jq -r 'to_entries[] | "\(.key), \(.value | .ip)"'

Sortie CSV et TSV

Les filtres @csv et @tsv peuvent également valoir la peine d’être pris en compte ici, par exemple.

jq -r 'to_entries[] | [.key, .value.ip] | @tsv'

produit:

Host1   10.1.2.3
Host2   10.1.2.2
Host3   10.1.18.1
72
peak

Est tombé sur une solution très élégante

jq 'with_entries(.value |= .ip)'

Quels résultats

{
  "Host1": "10.1.2.3",
  "Host2": "10.1.2.2",
  "Host3": "10.1.18.1"
}

Voici l'extrait de code jqplay avec lequel jouer: https://jqplay.org/s/Jb_fnBveMQ

La fonction with_entries convertit chaque objet de la liste d’objets en paire clé/valeur afin que nous puissions accéder à .key ou .value respectivement, nous mettons à jour (écrasons) chaque élément KV .value avec le champ .ip en utilisant update |= opérateur

21
Viacheslav