2016-10-11 4 views
5

Wie wähle ich mit jq ein übergeordnetes Objekt aus, wenn es ein untergeordnetes Objekt enthält, das zwei Filteranforderungen erfüllt?Verwenden von jq zum Auswählen eines übergeordneten Elements durch Durchsuchen des untergeordneten Schlüssels/Wertpaars

In diesem Beispiel möchte ich alle Subnets-Elemente auswählen, die ein Kind-Tag mit Schlüssel "Name" und Wert "TheName" haben. Mein Beispiel hat zwei Subnetze. Der erste hat "TheName" in der falschen Taste. Das zweite Subnetz hat das Name/Wert-Paar, nach dem ich suche. d. h. "Key": "Name", "Value": "TheName"

Im Folgenden wird ein Subnetz mit dem angegebenen Wert in einem der Tags, aber nicht im Paar ausgewählt. Es gibt beide Subnetze und nicht nur das zweite Subnetz zurück.

Wie verwende ich jq, um nur die Subnetze auszuwählen, die das Name/Wert-Paar haben, nach dem ich suche?

{ 
    "Subnets": [ 
     { 
      "VpcId": "vpc-12345678", 
      "SubnetId": "subnet-1234567a", 
      "Tags": [ 
       { 
        "Key": "IgnoreThis", 
        "Value": "TheName" 
       }, 
       { 
        "Key": "Name", 
        "Value": "NotTheName" 
       } 
      ] 
     }, 
     { 
      "VpcId": "vpc-12345678", 
      "SubnetId": "subnet-1234567b", 
      "Tags": [ 
       { 
        "Key": "IgnoreThis", 
        "Value": "ignore" 
       }, 
       { 
        "Key": "Name", 
        "Value": "TheName" 
       } 
      ] 
     } 
    ] 
} 

Das würde gewünschte Ausgabe sein:

{ 
    "VpcId": "vpc-12345678", 
    "SubnetId": "subnet-1234567b", 
    "Tags": [ 
     { 
      "Key": "IgnoreThis", 
      "Value": "ignore" 
     }, 
     { 
      "Key": "Name", 
      "Value": "TheName" 
     } 
    ] 
} 
+0

Wie die meisten gut geschriebene Unix-Befehle verwendet, 'jq' einen Dateinamen Argument lesen können, so dass [' cat' nutzlos ist] (http: // www .iki.fi/era/unix/award.html) – tripleee

Antwort

4

Angenommen, Ihre jq any/2 hat, wäre eine einfache und effiziente Lösung:

.Subnets[] 
| select(any (.Tags[]; .Key == "Name" and .Value == "TheName")) 

Dies erzeugt die Ausgabe, die Sie wollen, so dass ich werde es hier nicht wiederholen.

Wenn Ihr jq nicht any/2 hat, würde ich vorschlagen, Upgrade, aber wenn das unbequem oder nicht möglich ist, könnten Sie diese Def:

def any(f;g): reduce f as $i (false; . or ($i|g)); 

P. S. any(str; cond) kann gelesen werden als: 'Gibt es ein Element, e, im Stream, str, so dass e|cond einen anderen Wert als null oder false hat?'

+0

Fantastischer Gipfel! Ich habe die Dokumente auf "any" nicht verstanden. Die Dokumente und Beispiele auf jq sind nicht sehr klar. Es braucht mehr Beispiele wie dieses. Hoffentlich hilft der Fragetitel jemand anderem, Ihre Antwort zu finden! –

0

Hier ist eine Lösung, die indices

.Subnets[] | select(.Tags | indices({Key:"Name", Value:"TheName"}) != []) 
Verwandte Themen