analisa um campo de um array JSON no array bash

10

Eu tenho uma saída JSON que contém uma lista de objetos armazenados em uma variável. (Eu posso não estar falando direito)

[
  {
    "item1": "value1",
    "item2": "value2",
    "sub items": [
      {
        "subitem": "subvalue"
      }
    ]
  },
  {
    "item1": "value1_2",
    "item2": "value2_2",
    "sub items_2": [
      {
        "subitem_2": "subvalue_2"
      }
    ]
  }
]

Eu preciso de todos os valores para o item2 em uma matriz para que um script bash seja executado no Ubuntu 14.04.1.

Encontrei várias maneiras de obter o resultado inteiro em uma matriz, mas não apenas os itens de que preciso

    
por JpaytonWPD 07.01.2015 / 00:23

4 respostas

14

Usando :

$ cat json
[
  {
    "item1": "value1",
    "item2": "value2",
    "sub items": [
      {
        "subitem": "subvalue"
      }
    ]
  },
  {
    "item1": "value1_2",
    "item2": "value2_2",
    "sub items_2": [
      {
        "subitem_2": "subvalue_2"
      }
    ]
  }
]

CÓDIGO:

arr=( $(jq -r '.[].item2' json) )
printf '%s\n' "${arr[@]}"

OUTPUT:

value2
value2_2
    
por 07.01.2015 / 00:30
2

Graças ao sputnick, cheguei a isto:

arr=( $(curl -k https://localhost/api | jq -r '.[].item2') )

O JSON que tenho é a saída de uma API. Tudo o que eu precisava fazer wans remover o argumento do arquivo e pipe | a saída de curl para jq. Funciona muito bem e salvou alguns passos.

    
por 07.01.2015 / 01:39
1

O seguinte é realmente com bugs:

# BAD: Output line of * is replaced with list of local files; can't deal with whitespace
arr=$( curl -k "$url" | jq -r '.[].item2' )

Em vez disso, use:

# GOOD (with bash 4.x+), but can't detect failure
readarray -t arr < <(curl -k "$url" | jq -r '.[].item2' )

... ou melhor ainda ...

# GOOD (with bash 3.x+), *and* has nonzero status if curl or jq fails
IFS=$'\n' read -r -d '' -a arr \
  < <(set -o pipefail; curl --fail -k "$url" | jq -r '.[].item2' && printf '
# BAD: Output line of * is replaced with list of local files; can't deal with whitespace
arr=$( curl -k "$url" | jq -r '.[].item2' )
')
    
por 05.10.2016 / 05:02
0

como uma alternativa fácil, veja a ferramenta jtc (em link ), para conseguir a mesma coisa (como no exemplo de jq):

bash $ arr=( $(jtc -w '<item2>l+0' file.json) )
bash $ printf '%s\n' "${arr[@]}"
"value2"
"value2_2"
bash $ 

explicação sobre -w opção: colchetes angulares <...> especifica pesquisa json, sufixo l instrui para pesquisar rótulos em vez de valores, +0 instrui a localizar todas as ocorrências (em vez de apenas a primeira).

    
por 12.11.2018 / 19:00