jq를 사용하여 "Media" 속성(.session.attributeList 아래)에 "node7000" 문자열이 포함된 블록의 "name" 값을 가져오고 싶습니다(예제에서는 json 첫 번째 배열 블록이 일치합니다. 두 개가 있습니다). 일치:
"값": "노드 7000"
"value": "node7000 및 node8000"
예상되는 jq 출력은 다음과 같습니다.
"17200개 역"
[{
"name": "Station 17200",
"attributes": [{
"name": "EnableLog",
"value": "1"
}, {
"name": "LogFont",
"value": "0"
}, {
"name": "IdleTimer",
"value": "30"
}
],
"session": [{
"attributeList": [{
"name": "Launch",
"value": "1"
}, {
"name": "Media",
"value": "node7000"
}
]
}, {
"attributeList": [{
"name": "Group",
"value": "1"
}, {
"name": "RMedia",
"value": "1"
}
]
}, {
"attributeList": [{
"name": "Launch",
"value": ""
}, {
"name": "Media",
"value": "node7000 and node8000"
}
]
}
]
},
{
"name": "Station 17300",
"attributes": [{
"name": "EnableLog",
"value": "1"
}, {
"name": "LogFont",
"value": "0"
}, {
"name": "IdleTimer",
"value": "30"
}
],
"session": [{
"attributeList": [{
"name": "Launch",
"value": "1"
}, {
"name": "Media",
"value": "node6000"
}
]
}, {
"attributeList": [{
"name": "Group",
"value": "1"
}, {
"name": "RMedia",
"value": "1"
}
]
}, {
"attributeList": [{
"name": "Launch",
"value": ""
}, {
"name": "Media",
"value": "node6001"
}
]
}
]
}]
답변1
jq
해결책:
jq '.[] | select([.session[].attributeList[]
| .name == "Media" and (.value | contains("node7000"))
] | any ).name' jsonfile
.[]
- 입력 배열의 모든 요소(객체)를 반복합니다.select(<condition>)
<condition>
- 이 입력이 반환되면 함수는 입력을 변경하지 않고true
, 그렇지 않으면 출력을 생성하지 않습니다.contains(element)
- 필터 생성이 입력에 완전히 포함되어 있는지true
여부element
any
true
- 배열의 요소가 다음과 같은 경우 필터는 부울 값 배열을 입력으로 사용합니다.true
산출:
"Station 17200"
답변2
이는 다시 작성하는 방법을 보여주기 위한 것입니다.jq
RomanPerekhrest가 제안한 표현~하도록 하다함수 any(generator; condition)
형태any
사용:
.[] |
select(
any(
.session[].attributeList[];
.name == "Media" and (.value | contains("node7000"))
)
).name
이는 최상위 배열의 각 요소에서 모든 값을 추출하도록 함수에 지시합니다 any
. 그런 다음 각 요소에 대해 주어진 조건식을 사용하여 .session[].attributeList[]
이러한 요소에서 부울 배열을 생성 합니다. attributeList
부울 값이 있는 경우진짜를 선택한 다음 최상위 배열의 해당 요소를 선택합니다. name
그런 다음 키 값을 추출하여 인쇄합니다.
node7000
분명히 쿼리 문자열이 쉘 변수에 의존하도록 하려면 다음 --arg
을 사용하여 이를 표현식에 전달해야 합니다.
query_string=node7000
jq --arg media "$query_string" '.[] | select(any(.session[].attributeList[]; .name == "Media" and (.value | contains($media)))).name' file.json
PCRE에 문자열 대신 정규식을 전달하려면 contains($media)
로 변경하세요. test($media)
이를 통해 예를 들어 node7000
단어 경계 기호( \b
)를 사용하여 거짓 긍정 하위 문자열 대 문자열 일치의 위험을 피할 수 있습니다 node70001
.
jq --arg media '\bnode7000\b' '.[] | select(any(.session[].attributeList[]; .name == "Media" and (.value | test($media)))).name' file.json