json 파일을 반복하는 방법은 무엇입니까?

json 파일을 반복하는 방법은 무엇입니까?

name아래 json 파일이 있고 특정 값이 포함된 경우에만 호스트 ID를 가져오고 싶습니다 . 이를 달성하기 위해 쉘 스크립트를 사용하고 싶습니다.

{
  "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",
  }

}

예를 들어 이름에 'first-block'이 포함된 항목이 있으면 hosdId를 다음과 같이 가져와야 합니다.

166219e3-be5c-46d0-b4c7-33543a29ce32
176429e3-ae1d-46d0-b4c7-66123a24fa82

json 파일을 어떻게 반복할 수 있나요? 특정 값이 포함된 요소를 필터링 name하고 를 얻으려면 어떤 정규식을 사용해야 합니까 hostid?

답변1

jq를 사용할 수 있습니다.

입력 파일:

{
  "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"
    }
  ]
}

명령:

편집하다:@Runium의 기여로

$ jq '.items[] | select( .name | startswith("first-block-"))|.hostRef.hostId' < file.json 
"e70a2fe8fd0531ad1f87de49f03537a6"
"a85d2fe6fd0482ad1f54de49f45174a0"

답변2

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:])

이는 샘플 데이터의 형식이 다음과 같이 변경된 것입니다.

{
    "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"
        }
    ]
}

답변3

@Theophrastus가 언급했듯이 먼저 JSON 파서를 설치하고 싶습니다 jq. 그 후에는 원하는 값을 필터링하기만 하면 됩니다.

귀하가 게시한 JSON 블록이 유효하지 않다는 점을 언급하고 싶습니다. "items"의 여는 괄호는 닫혀 있지 않으며 두 번째 항목에는 items쉼표 구분 기호가 있어야 합니다. 그럼에도 불구하고, 나는 당신이 유효한 블록을 가지고 있고 관련성이 있다고 생각하는 부분만 잘라내어 붙여넣었다고 가정할 것입니다. 각 블록이 실제로 대표적인 경우 추가해야 할 것은 ( bash쉘이라고 가정) 뿐입니다.

echo "${YOUR_JSON_BLOCK}"  |  jq '.items[].hostRef.hostId'

YOUR_JSON_BLOCK이 데이터에 포함된 전체 유효한 json 문자열이라고 가정하고 지정된 대로 해당 행만 출력합니다.

답변4

최근에 나는 그런 json 쿼리를 처리하기 위한 더 쉬운 유닉스/셸 대안(완전히 FOSS이고 무료임)을 생각해냈습니다.jtc. 이 도구는 상대 걷기(즉, 하나를 찾아 다른 것으로 오프셋)를 처리합니다.

원래 json이 수정되었다고 가정하면(몇 가지 문제가 있음) cli는 다음과 같습니다.

bash $ cat file.json | jtc -w'[name]:<^first-block>R: [-1] [hostRef] [hostId]'
"166219e3-be5c-46d0-b4c7-33543a29ce32"
"176429e3-ae1d-46d0-b4c7-66123a24fa82"
bash $ 

관련 정보