2016-03-09 10 views
6

So habe ich eine JSON Klecks wie folgt:Verwenden von jq zum Extrahieren von Werten im JSON-Array mit einem bestimmten Schlüssel boolean == true?

[ 
    { 
    'id': 'something', 
    'isSparse': true 
    }, 
    ... 
] 

Wie schreibe ich einen jq Befehl, der dieses JSON blob auszufiltern werden und mir die IDs aller Einträge in dem Array drucken, die isSparse haben == wahr?

Ich habe versucht, die folgenden:

cat <blob> | jq -c '.[] | select(.operational | contains("true"))'

aber die folgende bekommen, weil offensichtlich true ein boolean ist und kein String:

jq: error: boolean and string cannot have their containment checked.

Antwort

2

Ich nehme an, du meinst isSparse. Der Filter select nimmt etwas auf, das einen booleschen Wert ergibt. isSparse ist bereits ein boolescher Wert, also müssen Sie ihn nur auswählen. contains wird verwendet, um zu überprüfen, ob sich etwas in einem anderen Container befindet (eine Zeichenfolge, ein Array, ein Objekt usw.).

$ jq -c '.[] | select(.isSparse)' <blob> 
8

Wenn die Aufgabe, "die IDs aller Einträge in dem Array zu drucken, die isSparse haben == true" ist, wird eine entsprechende jq Filter wäre:

.[] | select(.isSparse == true) | .id 

Wenn die Möglichkeit besteht, von .id Werte duplizieren, dann könnte die folgenden nur unterschiedliche Werte sichergestellt werden, emittiert:

map(select(.isSparse == true) | .id) | unique[] 

Wie @JeffMercado darauf hingewiesen, wenn .isSparse streng boolean ist, dann wählen Sie (.isSparse) ausreichen würde.

4

Ich füge diese Antwort hinzu, wie es in Zukunft für ein verwandtes Szenario hilfreich sein kann. - Ein spezifisches Beispiel hierfür wäre der Zugriff auf eine schlecht geschriebene API, die das gleiche Schlüssel/Wert-Paar abhängig davon, welcher Endpunkt oder welche Filter verwendet wurden, unterschiedlich zurückgibt. Dies ist sehr ärgerlich, wenn eine Schnittstelle, und der Wert ist eine Zeichenfolge, manchmal und ein boolean zu anderen Zeiten (weiterhin, manchmal sogar eine Zahl oder eine Zahl als String: |)


| tostring Hinzufügen des Wert vergleichen wie gewünscht;

cat <blob> | jq -c '.[] | select(.isSparse | tostring | contains("true"))'

oder nach einer exakten Übereinstimmung, leichte Variante:

cat <blob> | jq -c '.[] | select((.isSparse | tostring) == "true")'