スペースを考慮してjqを使用して情報をシェルに返すにはどうすればよいですか?

スペースを考慮してjqを使用して情報をシェルに返すにはどうすればよいですか?

このファイルが与えられたら:

$ 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出力を分割するシェルに依存するため、機能しません。改行は一種の空白なので、データから改行(タブや生の空白を含む)が失われます。

また、これらの試行は文字列データを参照できないため、文字列にファイル名のワイルドカードが含まれている場合は、ファイル名のワイルドカードを取得します。

同様の理由で最後の試みは失敗しましたが、データを正しくデコードできず、エンコードされた改行がそのまま残りました。


組み込み演算子@shin を使用して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>

答え2

ZSHにどのシェルを使用するかについては言及していません。

% fru=( ${(fQg::)"$(jq '.[].name' ~/tmp/fru)"} )
% for f in $fru; printf '<%s>\n' $f
<apple>
<banana
fofanna>
<my kiwi>
% =echo -n "<${fru[2]}>" | od -bc
0000000   074 142 141 156 141 156 141 012 146 157 146 141 156 156 141 076
           <   b   a   n   a   n   a  \n   f   o   f   a   n   n   a   >
0000020

jq呼び出しを実行し、f結果を改行に分割し、出力から文字列に残った引用符を削除しますQjqg:: 補間を実行するために組み込まれたエコーのように動作します。\n入力の文字列に。

答え3

@Kusalananda、@roaima、@StéphaneChazelasの回答とコメントに基づいて上記のコメントに記載されている同様の質問、私は次を見つけることができました:

list=$( jq -r ' .[].name | @sh ' fruits.json ) || exit 1
eval "fruits=( $list )" || exit 1
printf "<%s>\n" "${fruits[@]}"

関連情報