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


13

変数に格納されたオブジェクトのリストを含む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のすべての値が必要です。

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

回答:


17

使用:

$ 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

ファイルではなく変数からこれを行うことは可能ですか?不要なファイルシステムへのアクセスは避けたい。この配列をプルしたら、jsonの出力は完了です。
JpaytonWPD、2015年

1
何か試しましたか?
Gilles Quenot、2015年

2
jq . <<< "$json"シェル(bash)に関連していて、特定のものではありjq
ません

1
括弧がありません:arr=( $(...) )
Gilles Quenot、2015年

4
素晴らしいjqコマンドですが、コマンドの出力を解析して配列に変換しないでくださいarr=( $(...) )(たまたま、サンプル入力で機能する場合でも)。埋め込みまたは先頭/末尾の空白では意図したとおりに機能せず、誤ってグロブが発生する可能性があります。
mklement0 2016

5

以下は実際にはバギーです:

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

2

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

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

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


そのコードは実際には少しバグがあります。結果要素がある場合はどうなるか見てください*。現在のディレクトリにあるファイルのリストに置き換えられます。
Charles Duffy、

1
同様に、item2空白を含む値は複数の配列要素になります。
Charles Duffy

0

簡単な代替手段として、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オプションの説明:山括弧<...>はjson全体を検索することを指定し、接尾辞lは値ではなくラベルを検索する+0ように指示し、すべての出現箇所(最初のものだけではなく)を見つけるように指示します。


arr=( $(jq ...) )内容が文字列分割され、配列に入力するためにグロブ拡張されている限り、すべての回答と同じバグ-つまり、スペース(改行だけでなく)が新しい要素を作成し、グロブ式のように見える要素が、式が一致します。
Charles Duffy
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.