Use o JQ para gerar o CSV a partir da procura por faca

2

O JQ parece uma ótima ferramenta, mas eu estou lutando com isso. Aqui está o que estou tentando fazer: Extraia apenas os valores desta pesquisa de faca chef e gere um CSV.

dado este comando e saída:

knife search node "name:foo*" -a name -a cpu.total -a memory.total -Fj

{
  "results": 2,
  "rows": [
    {
      "foo-01": {
        "name": "foo-01",
        "cpu.total": 12,
        "memory.total": "16267368kB"
      }
    },
    {
      "foo-02": {
        "name": "foo-02",
        "cpu.total": 12,
        "memory.total": "16264296kB"
      }
    }
  ]
}

Gostaria de obter os valores extraídos para o CSV da seguinte forma:

foo-01,12,16267368kB
foo-02,12,16264296kB

(eu posso lidar com as citações)

    
por rb1980 22.07.2017 / 04:38

2 respostas

8
... | jq -r '.rows[] | .[] | [.name, .["cpu.total"], .["memory.total"]] | map(tostring) | join(",")'

Isto:

  1. Expande a matriz em .rows no fluxo de saída ( .rows.[] ).
  2. Canais que fluem para o próximo passo ( | ).
  3. Expande o objeto que é dado no valor único (neste caso) que ele continha ( .[] ).
  4. Cria uma matriz com os resultados de .name , .["cpu.total"] e .["memory.total"] cada um avaliado nesse objeto ( .[ .name, ... ] ).
  5. Converte todos os valores dessa matriz into strings ( map(tostring) ).
  6. Junta os elementos de cada matriz com uma vírgula ( join(",") ).

jq -r produz dados brutos , em vez de citar e escapar. A saída é então:

foo-01,12,16267368kB
foo-02,12,16264296kB

como você queria. Dependendo do seu analisador CSV & os dados reais, você pode precisar de citações extras em torno das strings, que você pode adicionar, ou usar @csv no lugar das duas últimas etapas.

... | jq -r '.rows[] | .[] | [.name, .["cpu.total"], .["memory.total"]] | @csv'

Poderíamos pular o map convertendo apenas o valor interno, o que leva alguns colchetes extras:

... | jq -r '.rows[]|.[]|[.name, (.["cpu.total"] | tostring), .["memory.total"]] | join(",")'

E provavelmente a alternativa mais feia:

... | jq -r '.rows[]|to_entries|.[]|.key + "," + (.value["cpu.total"] | tostring) + "," + .value["memory.total"]'

Nesse caso, não confiamos no campo .name e criamos a string inteira manualmente. Se você precisa de um formato altamente personalizado, essa é a opção mais flexível.

    
por 22.07.2017 / 05:09
1

Há provavelmente uma "regra do universo" que diz algo como "assim que você postar uma pergunta no SE, a resposta virá até você" ... Pouco tempo depois de postar essa pergunta, eu insisti com uma tentativa / google / loop rtfm e, eventualmente, surgiu com isso que funcionou para mim:

knife search node "name:foo*" -a name -a cpu.total -a memory.total -Fj | jq -r '.rows[] | map(.[]) | @csv '

Que retorna:

"foo-01",12,"16267000kB"
"foo-02",12,"16267000kB"

Isso importa diretamente para as folhas do google. Eu provavelmente posso ajustar isso ainda mais com alguns dos exemplos que Michael deu. Eu meio que prefiro isso, porque não preciso especificar os nomes dos campos explicitamente. Ansioso para jogar mais com o JQ, que ótima ferramenta!

    
por 22.07.2017 / 19:48

Tags