web-dev-qa-db-fra.com

jq: objet imbriqué, extraire l'ID de niveau supérieur et lever une valeur de l'objet interne

Étant donné les xample.json;

[
 {
  "id": 12345678,
  "stuff": { "book": "shelf", "hook": "line", "took": "off", "info-spec": 12 },
  "votes": 23
 },
 {
  "id": 12345679,
  "stuff": { "book": "maker", "hook": "sinker", "took": "pisin", "info-spec": 23 },
  "votes": 1
 }
]

Je peux extraire les id et votes facilement:

$ jq '.[] | { id, votes }' xample.json
{
  "votes": 23,
  "id": 12345678
}
{
  "votes": 1,
  "id": 12345679
}

Mais à quoi ressemblerait la requête pour extraire id et stuff.info-spec? La syntaxe évidente (pour moi) ne fonctionne pas du tout:

$ jq '.[] | { id, stuff.info-spec }' xample.json
error: syntax error, unexpected '.', expecting '}'
.[] | { id, stuff.info-spec }
                 ^
1 compile error

J'ai essayé stuff[info-spec] et stuff["info-spec"] aussi, mais bon, il me semble que je n'ai aucune idée de la façon de procéder.

Le tiret dans le nom de la clé semble compliquer encore les choses, mais ma compréhension limitée est que je peux contourner cela avec des guillemets doubles.

$ sed 's/votes/vo-tes/g' xample.json | jq '.[] | { id, "vo-tes" }'

donne la sortie attendue (c'est-à-dire similaire à ci-dessus sans le tiret dans "vo-tes").

Je peux extraire book:

$ jq '.[] | .stuff.book' xample.json

mais encore une fois ne peut pas comprendre la syntaxe de id et book; mais aussi, je ne peux pas extraire info-spec avec la même syntaxe:

$ jq '.[] | .stuff."info-spec"' xample.json
error: syntax error, unexpected QQSTRING_START, expecting IDENT
.[] | .stuff."info-spec"
             ^
1 compile error

Si je retire les guillemets, le message d'erreur est (prévisible) différent:

$ jq '.[] | .stuff.info-spec' xample.json
error: spec is not defined
.[] | .stuff.info-spec
                  ^^^^
1 compile error

Mais bon, ça marche:

$ jq '.[] | .stuff["info-spec"] ' xample.json
12
23

Ma sortie souhaitée pour cet exemple est alors

{
  "info-spec": 12,
  "id": 12345678
}
{
  "info-spec": 23,
  "id": 12345679
}

J'ai regardé le FAQ et le jq Cookbook mais je n'arrive pas à trouver quoi que ce soit une syntaxe pour "soulever" un élément de l'intérieur d'un objet à l'intérieur d'un autre objet.

20
tripleee

J'ai réussi à le comprendre.

$ jq '.[] | { id, "info-spec": .stuff["info-spec"] }' xample.json
{
  "info-spec": 12,
  "id": 12345678
}
{
  "info-spec": 23,
  "id": 12345679
}

La clé ici semble être d'utiliser le newkey: .complex["key"] notation pour le levage.

6
tripleee

intéressant, le problème est en effet le caractère "-" et cela fonctionne pour moi:

jq '.[] | { id, "info-spec": .stuff."info-spec" }' xample.json
{
  "id": 12345678,
  "info-spec": 12
}
{
  "id": 12345679,
  "info-spec": 23
}

pourtant, votre jq ne semble pas aimer cette syntaxe car elle s'est cassée sur ce qui suit et la mienne non:

jq '.[] | .stuff."info-spec"' xample.json
12
23

J'utilise:

jq --version
jq-1.4

edit: ressemble à un problème de version avec <1.4 en effet: https://github.com/stedolan/jq/issues/38

14
Hans Z.