각 경로와 값을 인쇄하고 싶습니다.JSON키값을 한 줄씩 담은 파일입니다. 다음과 같은 상황을 고려하여JSON그리고잭, 각 행의 값도 추가할 수 있나요? 사용하지 않는 경우잭다른 방법이 있나요? 나는 비슷한 것을 생각하고 있었다snmpwalk~을 위한JSON. 또한, 내가 하려는 일에 대한 기술적인 용어가 있나요?
$ cat short.json | jq '.'
{
"Reservations": [
{
"Groups": [],
"Instances": [
{
"ImageId": "ami-a",
"InstanceId": "i-a",
"InstanceType": "t2.micro",
"KeyName": "ubuntu"
}
]
}
]
}
$ cat short.json | jq -r '[paths | map(.|tostring) | join(".")]'
[
"Reservations",
"Reservations.0",
"Reservations.0.Groups",
"Reservations.0.Instances",
"Reservations.0.Instances.0",
"Reservations.0.Instances.0.ImageId",
"Reservations.0.Instances.0.InstanceId",
"Reservations.0.Instances.0.InstanceType",
"Reservations.0.Instances.0.KeyName"
]
여러 줄 출력의 한 줄 예:
"Reservations.0.Instances.0.ImageId": "ami-a",
출력을 다음에서 사용할 수 있도록 포맷할 수 있다면 좋을 것입니다.잭복사 및 붙여넣기를 사용하면 Linux Cut을 사용하여 값을 쉽게 구분할 수 있습니다.
'.Reservations[].Instances[].ImageId': "ami-a"
$ cat short.json | jq -r '.Reservations[].Instances[].ImageId'
ami-a
답변1
나는 이것에 대해 잘 모르지만 jq
인터넷에서 이것을 찾았고 그것이 귀하의 경우에 적용된다고 생각합니다.
잘라내어 붙여넣기 버전:
jq -r 'paths(scalars | true) as $p | [ ( [ $p[] | tostring ] | join(".") ), ( getpath($p) | tojson )] | join(": ")' short.json
읽기 쉬운 버전:
jq -r '
paths(scalars | true) as $p
| [ ( [ $p[] | tostring ] | join(".") )
, ( getpath($p) | tojson )
]
| join(": ")
' short.json
결과:
Reservations.0.Instances.0.ImageId: "ami-a"
Reservations.0.Instances.0.InstanceId: "i-a"
Reservations.0.Instances.0.InstanceType: "t2.micro"
Reservations.0.Instances.0.KeyName: "ubuntu"
보너스 포인트를 원하므로 sed
다음 트릭을 사용하여 원하는 결과를 얻을 수 있습니다.
... | sed "s/^/\'./; s/:/\':/; s/\.0/[]/g"
어떤 출력:
'.Reservations[].Instances[].ImageId': "ami-a"
'.Reservations[].Instances[].InstanceId': "i-a"
'.Reservations[].Instances[].InstanceType': "t2.micro"
'.Reservations[].Instances[].KeyName': "ubuntu"
답변2
다음 jq
표현식을 사용하여 출력의 키 부분과 값 부분이 모두 유효한 JSON인지 확인합니다(문자열인 경우 인코딩되고 따옴표 붙음, 부울, 숫자 또는 따옴표 없는 경우 따옴표 없음 null
). kv_to_str
읽기 쉽도록 키 값 문자열의 형식을 지정하는 도우미 함수를 만들었습니다 .
def kv_to_str($k; $v): "\($k): \($v)";
paths(scalars | true) as $p |
kv_to_str(
$p | join(".") | tojson;
getpath($p) | tojson
)
데이터에서 테스트해 보세요.
$ jq -r 'def kv_to_str($k;$v): "\($k): \($v)"; paths(scalars|true) as $p | kv_to_str($p|join(".")|tojson; getpath($p)|tojson)' file
"Reservations.0.Instances.0.ImageId": "ami-a"
"Reservations.0.Instances.0.InstanceId": "i-a"
"Reservations.0.Instances.0.InstanceType": "t2.micro"
"Reservations.0.Instances.0.KeyName": "ubuntu"
jq
각 값에 대해 쿼리하는 표현식으로 사용할 수 있는 것을 얻으려면 "Reservations.0.Instances.0.ImageId"
키를 생성할 필요가 없도록 약간의 조정을 수행할 수 있습니다 .["Reservations"][0]["Instances"][0]["ImageId"]
. 거기에 0을 남겨두었으므로 배열 요소에 대해 보다 구체적인 키를 생성할 수 있습니다.
def kv_to_str($k; $v): "\($k): \($v)";
paths(scalars | true) as $p |
kv_to_str(
"." + ($p | map([.] | tojson) | join(""));
getpath($p) | tojson
)
키는 경로의 각 부분을 가져와서 [...]
JSON으로 변환하여 생성됩니다(문자열은 따옴표로 묶이고 정수 인덱스는 따옴표 없이 유지됩니다). 그런 다음 조각을 연결하고 앞에 점을 추가합니다.
시험:
$ jq -r 'def kv_to_str($k;$v): "\($k): \($v)"; paths(scalars|true) as $p | kv_to_str("." + ($p|map([.]|tojson)|join("")); getpath($p)|tojson)' file
.["Reservations"][0]["Instances"][0]["ImageId"]: "ami-a"
.["Reservations"][0]["Instances"][0]["InstanceId"]: "i-a"
.["Reservations"][0]["Instances"][0]["InstanceType"]: "t2.micro"
.["Reservations"][0]["Instances"][0]["KeyName"]: "ubuntu"
$ jq -r '.["Reservations"][0]["Instances"][0]["InstanceType"]' file
t2.micro