このファイルが与えられたら:
$ cat fruits.json
[
{ "name": "apple" },
{ "name": "banana\nfofanna" },
{ "name": "my kiwi" }
]
jq
たとえば、配列を埋めるためにシェルがデータとして使用するフルーツ名のリストを取得するためにこれをどのように使用できますか?
fruits
次の配列割り当てと同じです。
$ fruits=(
'apple'
'banana
fofanna'
'my kiwi'
)
$ for f in "${fruits[@]}" ;do echo "<$f>"; done
<apple>
<banana
fofanna>
<my kiwi>
次のいずれも無効です。
$ fruits=( $(jq -r ' .[].name ' fruits.json))
$ fruits=( $(jq -r ' .[].name | @sh ' fruits.json))
$ fruits=( $(jq ' .[].name | @sh ' fruits.json))
ベストアンサー1
質問の最後の最初の2つの試みは、空白にjq
出力を分割するシェルに依存するため、機能しません。改行は一種の空白なので、データから改行(タブや生の空白を含む)が失われます。
また、これらの試行は文字列データを参照できないため、文字列にファイル名のワイルドカードが含まれている場合は、ファイル名のワイルドカードを取得します。
同様の理由で最後の試みは失敗しましたが、データを正しくデコードできず、エンコードされた改行がそのまま残りました。
組み込み演算子@sh
in を使用してjq
データを参照し、配列割り当てを構成します。
eval "$( jq -r '"fruits=(" + (map(.name)|@sh) + ")"' fruits.json )"
与えられたJSONデータに対して、現在のシェルは次の割り当てを評価して配列を作成しますfruits
。
fruits=('apple' 'banana
fofanna' 'my kiwi')
この声明を評価した後、
$ printf '<%s>\n' "${fruits[@]}"
<apple>
<banana
fofanna>
<my kiwi>
代わりに、追加name
シェル配列の各要素の値:
$ jq -r '"fruits+=(" + (.[].name | @sh) + ")"' fruits.json
fruits+=('apple')
fruits+=('banana
fofanna')
fruits+=('my kiwi')
$ unset -v fruits
$ eval "$(jq -r '"fruits+=(" + (.[].name | @sh) + ")"' fruits.json)"
$ printf '<%s>\n' "${fruits[@]}"
<apple>
<banana
fofanna>
<my kiwi>