아래에 json 파일이 있고 파일에 name
특정 값이 포함되어 있으면 호스트 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
jq
@Theophrastus가 언급했듯이 먼저 JSON 파서를 설치 해야 합니다 . 그런 다음 원하는 값을 필터링하면 됩니다.
귀하가 게시한 JSON 블록은 유효하지 않습니다. "항목"의 여는 괄호는 닫혀 있지 않으며 두 번째 항목에는 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 $