Quero listar alguns campos de uma estrutura JSON, incluindo um opcional, que está potencialmente em uma matriz com outros campos que não desejo exibir. Tenho usado select() para obter o valor do array que desejo, mas se eu tiver um objeto que não possui essa chave opcional, ele será ignorado. Deixe-me mostrar um exemplo. Aqui estão os dados:
[
{"field1":"1", "field2":"x", "Tags":[{"Key": "Name", "Value": "Name1"}, {"Key": "tag1", "Value": "tag1valuea"}]},
{"field1":"2", "field2":"y", "Tags":[{"Key": "Name", "Value": "Name2"}]},
{"field1":"3", "field2":"z", "Tags":[{"Key": "tag2", "Value": "tag2valueb"}]}
]
A saída que eu quero é:
1 x name1
2 y name2
3 z
Eu tentei:
jq -r '.[] | .field1 + " " + .field2 + " " + (.Tags[] | select(.Key == "Name") .Value)'
1 x Name1
2 y Name2
Mas, como você pode ver, ele elimina a terceira entrada porque não possui uma "Chave" definida como "Nome".
Então eu tentei:
jq -r '.[] | .field1 + " " + .field2 + " " + (.Tags[] | if(.Key == "Name") then .Value else null end)'
1 x Name1
1 x
2 y Name2
3 z
Você pode ver que acabei com duas entradas para o primeiro objeto porque ele tem um elemento extra no array com o qual não me importo.
Eu tentei inúmeras permutações das duas opções acima, sem sucesso. Espero que alguém tenha uma maneira inteligente de fazer com que jq não "esvazie" o item se ele não tiver a chave que estou selecionando e/ou repita quando houver itens na matriz que não desejo selecionar.
Imagino que existam muitas maneiras de fazer isso, e algumas provavelmente melhores, mas aqui está um
jq
filtro que faz isso (usando a--raw-output
opção).Exemplo de saída:
Experimente em jqplay.org .
Se
"Tags"
incluir vários.Key == "Name"
objetos, cada um"Value"
será anexado na mesma linha, como:Experimente isso em jqplay.org .
E se a
.Tags
matriz contiver mais de uma correspondência? Digamos que havia um terceiro item{"Key": "Name", "Value": "AnotherName"}
na.Tags
matriz do primeiro registro ("1 x"). Você preferiria como saída uma linha combinada como1 x Name1 AnotherName
, ou melhor, duas linhas separadas como1 x Name1
e1 x AnotherName
? De qualquer forma, aqui estão as duas variantes usando interpolação de string e mostrando saídas baseadas na entrada estendida com a correspondência adicionada mencionada acima.Linhas combinadas ( Demo ):
Linhas separadas ( Demonstração ):