JQ를 사용하여 칼 검색에서 CSV 생성

JQ를 사용하여 칼 검색에서 CSV 생성

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(",")'

이것:

  1. 배열 확장.rows출력 스트림에 대한 입력 ( .rows.[])입니다.
  2. 흐르는 파이프다음 단계( |)로 이동합니다.
  3. 지정된 개체를 (이 경우) 포함된 단일 값( .[])으로 확장합니다.
  4. 배열을 생성.name, .["cpu.total"], 의 결과.["memory.total"] 각각은 객체를 평가합니다.( .[ .name, ... ]).
  5. 모든 값 변환배열의문자열로( map(tostring)).
  6. 요소 연결각 배열 앞에는 쉼표( 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를 더 많이 사용하게 되기를 기대합니다. 정말 훌륭한 도구입니다!

답변3

표현 jq방식

.rows[] | map(.[]) | @csv

존재하다당신만의 대답매우 깔끔하지만 가져가세요마이클의 고민키 순서를 고려하여 필요한 값을 명시적으로 추출할 수 있습니다.

.rows[][] | [ .name, ."cpu.total", ."memory.total" ] | @csv

또는,

.rows[] | map( .name, ."cpu.total", ."memory.total" ) | @csv

관련 정보