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 $