Ich habe die folgende JSON-Datei und möchte die Host-ID nur dann abrufen, wenn sie name
einen bestimmten Wert enthält. Dazu möchte ich ein Shell-Skript verwenden.
{
"items" : [ {
"name" : "first-block-e70a2fe8fd0531ad1f87de49f03537a6",
"type" : "STORE",
"hostRef" : {
"hostId" : "166219e3-be5c-46d0-b4c7-33543a29ce32"
},
"roleState" : "STARTED",
"healthSummary" : "GOOD",
},
{
"name" : "second-block-c21a1ae8dd2831cd1b87de49f98274e8",
"type" : "STORE",
"hostRef" : {
"hostId" : "176429e3-be5c-46d0-b4c7-33543a29ad63"
},
"roleState" : "STARTED",
"healthSummary" : "GOOD",
}
{
"name" : "first-block-a85d2fe6fd0482ad1f54de49f45174a0",
"type" : "STORE",
"hostRef" : {
"hostId" : "176429e3-ae1d-46d0-b4c7-66123a24fa82"
},
"roleState" : "STARTED",
"healthSummary" : "GOOD",
}
}
Beispiel: Wenn der Name etwas mit 'first-block' enthält, dann sollte ich die hosdId erhalten als
166219e3-be5c-46d0-b4c7-33543a29ce32
176429e3-ae1d-46d0-b4c7-66123a24fa82
Wie kann ich die JSON-Datei durchlaufen? Welchen regulären Ausdruck sollte ich verwenden, um das Element zu filtern, das einen bestimmten Wert enthält, name
und das abzurufen hostid
?
Antwort1
Sie könnten jq verwenden:
Eingabedatei:
{
"items" : [
{
"name" : "first-block-e70a2fe8fd0531ad1f87de49f03537a6",
"type" : "STORE",
"hostRef" : {
"hostId" : "166219e3-be5c-46d0-b4c7-33543a29ce32"
},
"roleState" : "STARTED",
"healthSummary" : "GOOD"
},
{
"name" : "second-block-c21a1ae8dd2831cd1b87de49f98274e8",
"type" : "STORE",
"hostRef" : {
"hostId" : "176429e3-be5c-46d0-b4c7-33543a29ad63"
},
"roleState" : "STARTED",
"healthSummary" : "GOOD"
},
{
"name" : "first-block-a85d2fe6fd0482ad1f54de49f45174a0",
"type" : "STORE",
"hostRef" : {
"hostId" : "176429e3-ae1d-46d0-b4c7-66123a24fa82"
},
"roleState" : "STARTED",
"healthSummary" : "GOOD"
}
]
}
Befehl:
Bearbeiten:mit @Runiums Beitrag
$ jq '.items[] | select( .name | startswith("first-block-"))|.hostRef.hostId' < file.json
"e70a2fe8fd0531ad1f87de49f03537a6"
"a85d2fe6fd0482ad1f54de49f45174a0"
Antwort2
Ein sehr einfaches Beispiel mit Python:
#!/usr/bin/env python
import sys
import json
def print_first(data):
for item in data["items"]:
if item["name"].startswith("first"):
print item["hostRef"]["hostId"]
def main(argv):
for json_file in argv:
with open(json_file) as data_file:
data = json.load(data_file)
print_first(data)
if __name__ == "__main__":
main(sys.argv[1:])
Das geschieht mit Ihren Beispieldaten, die wie folgt neu formatiert wurden:
{
"items" : [
{
"name" : "first-block-e70a2fe8fd0531ad1f87de49f03537a6",
"type" : "STORE",
"hostRef" : {
"hostId" : "166219e3-be5c-46d0-b4c7-33543a29ce32"
},
"roleState" : "STARTED",
"healthSummary" : "GOOD"
},
{
"name" : "second-block-c21a1ae8dd2831cd1b87de49f98274e8",
"type" : "STORE",
"hostRef" : {
"hostId" : "176429e3-be5c-46d0-b4c7-33543a29ad63"
},
"roleState" : "STARTED",
"healthSummary" : "GOOD"
},
{
"name" : "first-block-a85d2fe6fd0482ad1f54de49f45174a0",
"type" : "STORE",
"hostRef" : {
"hostId" : "176429e3-ae1d-46d0-b4c7-66123a24fa82"
},
"roleState" : "STARTED",
"healthSummary" : "GOOD"
}
]
}
Antwort3
Wie @Theophrastus erwähnt hat, möchten Sie zuerst den JSON-Parser installieren jq
. Danach müssen Sie nur noch nach dem gewünschten Wert filtern.
Ich sollte erwähnen, dass der von Ihnen gepostete JSON-Block nicht gültig ist; die öffnende Klammer von „items“ ist nicht geschlossen und der zweite Eintrag items
sollte durch ein Komma getrennt sein. Trotzdem gehe ich davon aus, dass Sie einen gültigen Block haben und nur das ausgeschnitten und eingefügt haben, was Sie für relevant hielten. Wenn jeder Block tatsächlich repräsentativ ist, müssen Sie nur Folgendes hinzufügen (vorausgesetzt, das bash
ist Ihre Shell):
echo "${YOUR_JSON_BLOCK}" | jq '.items[].hostRef.hostId'
Dadurch werden nur die angegebenen Zeilen ausgegeben, vorausgesetzt, YOUR_JSON_BLOCK ist die vollständige gültige JSON-Zeichenfolge mit Ihren Daten.
Antwort4
vor kurzem habe ich eine einfachere Unix/Shell-Alternative entwickelt (sie ist vollständig FOSS und kostenlos), um mit solchen JSON-Abfragen umzugehen - werfen Sie einen Blick aufjtc
. Das Tool ermöglicht die Handhabung relativer Spaziergänge (d. h. das Finden eines Spaziergangs und anschließendes Versetzen in einen anderen).
vorausgesetzt, Ihr ursprünglicher JSON-Code ist repariert (er weist einige Probleme auf), würde die CLI folgendermaßen aussehen:
bash $ cat file.json | jtc -w'[name]:<^first-block>R: [-1] [hostRef] [hostId]'
"166219e3-be5c-46d0-b4c7-33543a29ce32"
"176429e3-ae1d-46d0-b4c7-66123a24fa82"
bash $