466 Stimmen

Wähle Objekte basierend auf dem Wert der Variable im Objekt unter Verwendung von jq aus

Ich habe die folgende JSON-Datei:

{
    "FOO": {
        "name": "Donald",
        "location": "Stockholm"
    },
    "BAR": {
        "name": "Walt",
        "location": "Stockholm"
    },
    "BAZ": {
        "name": "Jack",
        "location": "Wo auch immer"
    }
}

Ich benutze jq und möchte die "name" Elemente der Objekte erhalten, bei denen 'location' 'Stockholm' ist.

Ich weiß, dass ich alle Namen bekommen kann, indem ich

cat json | jq .[] | jq ."name"
"Jack"
"Walt"
"Donald"

aber ich kann nicht herausfinden, wie ich nur bestimmte Objekte ausgeben kann, basierend auf dem Wert eines Untertasten (hier: "location" : "Stockholm").

667voto

Daniel Punkte 10377

Adaptiert von diesem Beitrag auf Processing JSON with jq, kannst du das select(bool) wie folgt verwenden:

$ jq '.[] | select(.location=="Stockholm")' json
{
  "location": "Stockholm",
  "name": "Walt"
}
{
  "location": "Stockholm",
  "name": "Donald"
}

307voto

peak Punkte 86238

Um einen Strom nur mit den Namen zu erhalten:

$ jq '.[] | select(.location=="Stockholm") | .name' json

ergibt:

"Donald"
"Walt"

Um einen Strom entsprechender (Schlüsselname, "name" Attribut) Paare zu erhalten, beachten Sie:

$ jq -c 'to_entries[]
        | select (.value.location == "Stockholm")
        | [.key, .value.name]' json

Ausgabe:

["FOO","Donald"]
["BAR","Walt"]

57voto

spazm Punkte 3931

Ich hatte eine ähnliche Frage: Was ist, wenn Sie das ursprüngliche Objektformat zurückhaben möchten (mit Schlüsselnamen, z.B. FOO, BAR)?

Jq bietet to_entries und from_entries zur Konvertierung zwischen Objekten und Key-Value-Paar-Arrays. Das zusammen mit map um das select.

Diese Funktionen konvertieren zwischen einem Objekt und einem Array von Schlüssel-Wert-Paaren. Wenn to_entries ein Objekt übergeben wird, enthält das Ausgabearray für jeden k: v-Eintrag im Eingabearray {"key": k, "value": v}.

from_entries führt die umgekehrte Konvertierung durch, und with_entries (foo) ist eine Abkürzung für to_entries | map(foo) | from_entries, die nützlich ist, um eine Operation an allen Schlüsseln und Werten eines Objekts durchzuführen. from_entries akzeptiert Schlüssel, Key, name, Name, value und Value als Schlüssel.

jq15 < json 'to_entries | map(select(.value.location=="Stockholm")) | from_entries'

{
  "FOO": {
    "name": "Donald",
    "location": "Stockholm"
  },
  "BAR": {
    "name": "Walt",
    "location": "Stockholm"
  }
}

Unter Verwendung der with_entries Abkürzung wird dies zu:

jq15 < json 'with_entries(select(.value.location=="Stockholm"))'
{
  "FOO": {
    "name": "Donald",
    "location": "Stockholm"
  },
  "BAR": {
    "name": "Walt",
    "location": "Stockholm"
  }
}

35voto

Yordan Georgiev Punkte 4516

Nur versuchen Sie dies als vollständige Kopie im Shell und Sie werden es erfassen.

# Übergeben Sie den mehrzeiligen String an das jq, verwenden Sie das jq, um
# das Attribut mit dem Namen "card_id" auszuwählen
# NUR wenn sein Nachbarattribut
# mit dem Namen "card_id_type" den Wert "card_id_type-01" hat.
# jq -r bedeutet gib mir NUR den Wert der jq-Abfrage ohne Anführungszeichen aka raw

cat << EOF | \
    jq -r '.[]| select (.card_id_type == "card_id_type-01")|.card_id'
    [  
     { "card_id": "id-00", "card_id_type": "card_id_type-00"},
     { "card_id": "id-01", "card_id_type": "card_id_type-01"},
     { "card_id": "id-02", "card_id_type": "card_id_type-02"}
    ]
EOF
# das ^^^ MUSS zuerst in der Zeile beginnen - kein Leerzeichen dort !!!
# Ausgänge:
# id-01

oder mit einem aws cli Befehl

 # list meine vpcs oder
 # list die Werte der Tags, deren Namen "Name" sind
 aws ec2 describe-vpcs | jq -r '.| .Vpcs[].Tags[]
        |select (.Key == "Name") | .Value'|sort  -nr

Beachten Sie, dass Sie sich sowohl während der Filterphase als auch während der Auswahlphase in der Hierarchie nach oben und unten bewegen könnten:

 kubectl get services --all-namespaces -o json | jq -r '
 .items[] | select( .metadata.name 
     | contains("my-srch-string")) | 
     { name: .metadata.name, ns: .metadata.namespace 
     , nodePort: .spec.ports[].nodePort
     , port: .spec.ports[].port}
 '

0voto

James Gaul Punkte 47

Hoffentlich hilft dies anderen, ich habe jq in Hunderten von meinen eigenen Skripten verwendet, aber ich kämpfe jedes einzelne Mal damit, Variablen darin zu verwenden... in diesem Fall war dies der einzige Weg, um eine Zahlenvariable zu übergeben (d.h. einfache Anführungszeichen um das Argument/die Variable):

id=26533

cat mydata.json | jq -r --arg id "$id" '.sensor[] |
select(.objid=='$id').probe'

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X