블록의 다른 속성 값을 기반으로 이름 값 가져오기

블록의 다른 속성 값을 기반으로 이름 값 가져오기

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
  • anytrue- 배열의 요소가 다음과 같은 경우 필터는 부울 값 배열을 입력으로 사용합니다.true

산출:

"Station 17200"

답변2

이는 다시 작성하는 방법을 보여주기 위한 것입니다.jqRomanPerekhrest가 제안한 표현~하도록 하다함수 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

관련 정보