셸에서 JSON 출력을 구문 분석하는 방법은 무엇입니까?
예를 들어 Amazon Web Services는 인스턴스 상태를 검색하는 CLI를 제공합니다.
$ aws ec2 describe-instances <my_instance_id>
그러나 명령은 JSON 문자열을 반환합니다. 이 명령의 출력은 다음과 같습니다.
$ aws ec2 describe-instances x12345
{
"Reservations" :
{
"OwnerId": "1345345"
"Groups": [],
"SecurityGroups": [
{
"Foo" : "yes"
"Bar" : "no
}
]
}
}
JSON 출력을 구문 분석하는 데 사용할 수 있는 내장 셸이 있나요?
예를 들어, 쉘 변수에 FOO
다음을 캡처하고 싶습니다 output["Reservations"]["SecurityGroups"][0]{"Foo"}
.
특히 도움이 된다면 Zsh에서 작동하는 솔루션에 관심이 있습니다.
답변1
제가 알기로는 당신은 "Foo"의 가치를 찾고 있는 것 같습니다. 이것은진짜이는 쉘 명령줄 도구를 사용하여 쉽게 수행할 수 있습니다 jq
. sed
자체 파서 언어를 구현하는 것과 같습니다. 귀하의 예를 들면 다음과 같습니다.
json='
{
"Reservations" :
{
"OwnerId" : "1345345",
"Groups" : [],
"SecurityGroups" : [
{
"Foo" : "yes",
"Bar" : "no"
}
]
}
}'
jq
yes
다음을 통해 간단하게 얻을 수 있습니다.
printf %s "$json" |
jq '.[].SecurityGroups[0].Foo?'
산출
"yes"
기호를 사용하여 객체 해시 또는 사전 목록을 반복 할 수 .dot
있으며 짐작할 수 있듯이 숫자 대괄호 인덱싱을 사용하여 더 간단하게 배열을 인덱싱할 수 있습니다. 위 명령에서는 빈 인덱스 형식을 사용하여 해당 수준에서 모든 반복 가능 항목을 확장하고 싶다는 것을 나타냅니다. 다음과 같이 이해하는 것이 더 쉬울 수 있습니다.
printf %s "$json" | jq '.[][]'
...이것은 배열의 두 번째 수준 항목에 대한 모든 값을 분석하고...
"1345345"
[]
[
{
"Foo": "yes",
"Bar": "no"
}
]
이는 jq
기능의 표면만 긁는 것입니다. 이는 셸에서 데이터를 직렬화하는 매우 강력한 도구이며, 클래식 Unix 스타일로 단일 실행 가능 바이너리로 컴파일하고, 배포판의 패키지 관리자를 통해 사용할 수 있으며, 좋은 문서가 많이 있습니다. 꼭 방문해 보세요git
-페이지직접 확인해보세요.
계층적 데이터를 처리하는 또 다른 방법인 BTW json
(적어도 작업 중인 내용을 이해함)는 다른 방향으로 가서 표기법을 사용하여 .dot
중단하는 것일 수 있습니다.모두값은모두다음과 같은 수준:
printf %s "$json" | jq '..'
{
"Reservations": {
"OwnerId": "1345345",
"Groups": [],
"SecurityGroups": [
{
"Foo": "yes",
"Bar": "no"
}
]
}
}
{
"OwnerId": "1345345",
"Groups": [],
"SecurityGroups": [
{
"Foo": "yes",
"Bar": "no"
}
]
}
"1345345"
[]
[
{
"Foo": "yes",
"Bar": "no"
}
]
{
"Foo": "yes",
"Bar": "no"
}
"yes"
"no"
jq
그러나 더 나은 접근 방식은 다양한 유형의 노드에 대해 제공되는 많은 검색 또는 검색 방법 중 하나를 사용하는 것입니다 .
답변2
이것이 당신의 목표에 대한 답이지만 당신의 문제는 아닙니다. 이는 목표를 달성하기 위해 JSON 파서를 사용할 필요가 없음을 의미합니다.
AWS cli 유틸리티에는 매개변수만 사용하여 선택 필드를 출력하는 기능이 있습니다 --query
. 이것은 문서화되어 있습니다.여기.
예를 들어:
$ aws ec2 describe-instances \
--query 'Reservations[0].Instances[0].SecurityGroups[0].GroupName' \
--instance-id i-6b272337 \
--output text
mongodb
원하는 경우 여러 필드를 선택할 수도 있습니다.
$ aws ec2 describe-instances \
--query 'Reservations[0].Instances[0].SecurityGroups[0].[GroupName,GroupId]' \
--instance-id i-6b272337 \
--output text
mongodb sg-710ffa14
일치하는 여러 구조를 표시할 수도 있습니다.
$ aws ec2 describe-instances \
--query 'Reservations[0].Instances[0].SecurityGroups[*].[GroupName,GroupId]' \
--instance-id i-6b272337 \
--output text
mongodb sg-710ffa14
default sg-a0243bcc