parsing satu bidang dari array JSON ke bash array


13

Saya memiliki output JSON yang berisi daftar objek yang disimpan dalam variabel. (Saya mungkin tidak mengatakan itu benar)

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

Saya membutuhkan semua nilai untuk item2 dalam array untuk skrip bash untuk dijalankan di ubuntu 14.04.1.

Saya telah menemukan banyak cara untuk mendapatkan seluruh hasil ke dalam array tetapi tidak hanya item yang saya butuhkan

Jawaban:


17

Menggunakan :

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

KODE:

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

KELUARAN:

value2
value2_2

Apakah mungkin untuk melakukan ini dari variabel, bukan file? Saya mencoba untuk menghindari akses sistem file yang berlebihan jika saya tidak membutuhkannya. Setelah saya menarik array ini saya selesai dengan output json.
JpaytonWPD

1
Sudahkah Anda mencoba sesuatu?
Gilles Quenot

2
jq . <<< "$json"itu terkait shell (bash), tidak spesifik untukjq
Gilles Quenot

1
Tanda kurung hilang:arr=( $(...) )
Gilles Quenot

4
Besar jqperintah, tapi tolong jangan parse output perintah ke dalam sebuah array dengan arr=( $(...) )(meskipun itu terjadi kerja dengan input sampel): itu tidak bekerja sebagaimana dimaksud dengan tertanam atau terkemuka / trailing spasi dan dapat mengakibatkan globbing disengaja.
mklement0

5

Berikut ini sebenarnya buggy:

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

Sebaliknya, gunakan:

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

... atau, bahkan lebih baik ...

# 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 '\0')

2

Berkat sputnick saya dapat ini:

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

JSON yang saya miliki adalah output dari API. Yang perlu saya lakukan adalah menghapus argumen file dan menyalurkan |output dari curl ke jq. Berfungsi bagus dan menyimpan beberapa langkah.


Kode itu sebenarnya agak buggy. Lihatlah apa yang terjadi jika Anda memiliki elemen hasil *- itu akan diganti dengan daftar file di direktori Anda saat ini.
Charles Duffy

1
Demikian pula, item2nilai dengan spasi putih di dalamnya akan menjadi lebih dari satu elemen array.
Charles Duffy

0

sebagai alternatif yang mudah, lihat jtcalat (di https://github.com/ldn-softdev/jtc ), untuk mencapai hal yang sama (seperti dalam contoh jq):

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

penjelasan tentang -wopsi: kurung sudut <...>menentukan pencarian seluruh json, akhiran lmenginstruksikan untuk mencari label daripada nilai, +0menginstruksikan untuk menemukan semua kejadian (bukan hanya yang pertama).


Bug yang sama dengan semua arr=( $(jq ...) )jawaban, sejauh kontennya dipecah-string dan dikembangkan-glob untuk mengisi array - ruang yang berarti (bukan hanya baris baru) membuat elemen baru, dan elemen yang terlihat seperti ekspresi bola digantikan oleh file yang ekspresi cocok.
Charles Duffy
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.