Wie durchlaufe ich eine JSON-Datei?

Wie durchlaufe ich eine JSON-Datei?

Ich habe die folgende JSON-Datei und möchte die Host-ID nur dann abrufen, wenn sie nameeinen 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, nameund 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 itemssollte 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 bashist 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 $ 

verwandte Informationen