JQ는 훌륭한 도구처럼 보이지만 사용하는 데 어려움을 겪고 있습니다. 제가 하고 싶은 일은 셰프의 칼 검색에서 값만 추출하여 CSV를 생성하는 것입니다.
다음 명령과 출력이 주어지면:
Knife는 "name:foo*" 노드를 검색합니다. -a name -a cpu.total -a memory.total -Fj
{ "결과": 2, "좋아요":[ { "foo-01":{ "이름": "foo-01", "CPU.총계": 12, "메모리.전체": "16267368kB" } }, { "foo-02": { "이름": "foo-02", "CPU.총계": 12, "메모리.전체": "16264296kB" } } ] }
다음과 같이 값을 CSV로 추출하고 싶습니다.
foo-01,12,16267368kB foo-02,12,16264296kB
(인용문을 처리할 수 있습니다)
답변1
... | jq -r '.rows[] | .[] | [.name, .["cpu.total"], .["memory.total"]] | map(tostring) | join(",")'
이것:
- 배열 확장
.rows
출력 스트림에 대한 입력 (.rows.[]
)입니다. - 흐르는 파이프다음 단계(
|
)로 이동합니다. - 지정된 개체를 (이 경우) 포함된 단일 값(
.[]
)으로 확장합니다. - 배열을 생성
.name
,.["cpu.total"]
, 의 결과.["memory.total"]
각각은 객체를 평가합니다.(.[ .name, ... ]
). - 모든 값 변환배열의문자열로(
map(tostring)
). - 요소 연결각 배열 앞에는 쉼표(
join(",")
)가 붙습니다.
jq -r
원시 데이터 출력, 인용하고 이스케이프하는 대신. 그러면 출력은 다음과 같습니다.
foo-01,12,16267368kB
foo-02,12,16264296kB
당신이 원하는대로. CSV 파서 및 실제 데이터에 따라 문자열 주위에 추가 따옴표를 추가해야 할 수도 있습니다. 이러한 따옴표를 추가할 수 있습니다.또는 사용@csv
마지막 두 단계를 교체하십시오.
... | jq -r '.rows[] | .[] | [.name, .["cpu.total"], .["memory.total"]] | @csv'
map
내부에 하나의 값만 변환하면 이 작업을 건너뛸 수 있으며, 여기에는 추가 괄호가 필요합니다.
... | jq -r '.rows[]|.[]|[.name, (.["cpu.total"] | tostring), .["memory.total"]] | join(",")'
아마도 가장 추악한 옵션은 다음과 같습니다.
... | jq -r '.rows[]|to_entries|.[]|.key + "," + (.value["cpu.total"] | tostring) + "," + .value["memory.total"]'
이 경우 해당 필드에 의존하지 않고 .name
전체 문자열을 수동으로 작성합니다. 고도로 사용자 정의된 형식이 필요한 경우 가장 유연한 옵션입니다.
답변2
"SE에 질문을 게시하면 답변이 나타납니다"라는 "우주의 법칙"이 있을 수 있습니다... 이 질문을 게시한 직후 try/google/rtfm 루프에 갇혀 마침내 알아냈습니다. 나에게 도움이 된 방법은 다음과 같습니다.
Knife는 노드 "name:foo*"를 검색합니다. -a name -a cpu.total -a memory.total -Fj | jq -r '.rows[] | jq -r '.rows[] |map(.[]) @csv' |
반품:
"foo-01",12,"16267000kB" "foo-02",12,"16267000kB"
이는 Google 스프레드시트로 깔끔하게 가져옵니다. 아마도 Michael이 제공한 몇 가지 예를 사용하여 이것을 더 조정할 수 있을 것입니다. 필드 이름을 명시적으로 지정할 필요가 없기 때문에 이것이 마음에 듭니다. JQ를 더 많이 사용하게 되기를 기대합니다. 정말 훌륭한 도구입니다!