web-dev-qa-db-ja.com

JSON配列の1つのフィールドをbash配列に解析します

変数に格納されたオブジェクトのリストを含むJSON出力があります。 (私はその権利を表現していないかもしれません)

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

Bashスクリプトをubuntu 14.04.1で実行するには、配列内のitem2のすべての値が必要です。

結果全体を配列に入れる方法がたくさん見つかりましたが、必要なアイテムだけではありません

14
JpaytonWPD

jq の使用:

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

コード:

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

出力:

value2
value2_2
18
Gilles Quenot

以下は実際にはバグがあります:

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

代わりに、次を使用します。

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

...または、さらに良い...

# 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')
6
Charles Duffy

Sputnickのおかげで私はこれに到達しました:

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

私が持っているJSONは、APIからの出力です。ファイルの引数を削除し、curlの出力を|をjqにパイプするために必要なことはすべてです。うまく機能し、いくつかのステップを節約しました。

2
JpaytonWPD

簡単な代替手段として、jtcツール( https://github.com/ldn-softdev/jtc )を見て、同じことを実現します(jqの例と同様)。

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

-wオプションの説明:angular角かっこ<...>は、json全体の検索を指定し、接尾辞lは、値ではなくラベルを検索するように指示します+0 (最初のものだけでなく)すべての出現箇所を検索するように指示します。

0
Dmitry L.