web-dev-qa-db-fra.com

JSON JQ si sans autre

J'utilise la commande JQ suivante pour filtrer le JSON. Mon exigence est de filtrer le message JSON si le nœud attendu est présent. Ou bien, ne faites rien. Par conséquent, j'utilise si, Elif, ....

sed -n "s/.*Service - //p" $1/response.log* |
  jq "if (.requests | length) != 0 then .requests |= map(select(.id == \"123\"))
      Elif (.result | length ) != 0  then .result |= map(select(.id== \"123\")) 
      else " "  end" > ~/result.log

Il semble que le reste soit obligatoire ici. Je ne veux rien faire dans le bloc else. Y at-il de toute façon, je peux ignorer autre chose ou simplement imprimer des blancs à l'intérieur d'autre.

Dans le cas ci-dessus, il imprime des guillemets doubles "" dans le fichier de résultat.

19
user1578872

Vous pouvez utiliser l'idiome:

if CONDITION then WHATEVER else empty end

empty est un filtre qui ne produit rien du tout - pas même null, ce qui est après tout quelque chose (à savoir une valeur JSON). C'est un peu comme un trou noir, seulement plus noir - il consommera tout ce qu'il propose, mais contrairement à un trou noir, il n'émet même pas de rayonnement Hawking.

Dans votre cas, vous avez un "Elif" donc utiliser "else empty" est probablement ce que vous voulez, mais pour référence, ce qui précède est exactement équivalent à:

select(CONDITION) | WHATEVER

P.S. Je suppose que quel que soit l'objectif de la commande sed, cela pourrait être fait de manière plus fiable dans le cadre du programme jq, peut-être en utilisant walk/1.

MISE À JOUR

Après la sortie de jq 1.6, une modification a été apportée pour que "si sans autre" ait la sémantique de "si _ alors _ sinon. Fin", c'est-à-dire:

if P then Q end === if P then Q else . end

34
peak

Puisque vous n'apportez aucune modification supplémentaire à l'objet, utilisez simplement le filtre "identité" ..

if (.requests | length) then ... else . end

En revanche, vous mettez simplement à jour la propriété requests ou result si elle n'est pas vide en utilisant map. Le contrôle n'est pas nécessaire. S'il est vide, il reviendra vide.

Vous pouvez simplifier votre filtre pour simplement:

.requests |= map(select(.id == \"123\")) | .result |= map(select(.id== \"123\"))
3
Jeff Mercado