単一の式のみを使用してコマンドの出力を分割し、結果を配列に割り当てるにはどうすればよいでしょうか?

単一の式のみを使用してコマンドの出力を分割し、結果を配列に割り当てるにはどうすればよいでしょうか?

注意:私は他の同様の質問への回答を読みました(出力を分割して配列に保存するにはどうすればよいでしょうか?bashで文字列を配列に分割する方法) ですが、どれも私がここで尋ねている具体的な質問に答えていません。


あるコマンドの出力がfoo10個のタブ区切りフィールドからなる1行であると仮定します。

tmpvar=$( foo )
fields=( ${(ps:\t:)tmpvar} )
echo $#fields
# 10

質問:fooへの中間割り当てを必要とせずに、タブで の出力の同様の分割を実現するにはどうすればよいでしょうかtmpvar?


ちなみに、これは機能しません:

fields=( ${(ps:\t:)$( foo )} )
echo $#fields
# 1

答え1

$ printf '<%s>\n' "${(@ps:\t:)$(printf 'foo bar\t\tbaz')}"
<foo bar>
<>
<baz>

または、tempvar アプローチのように空の要素を抑制したい場合:

$ printf '<%s>\n' ${(ps:\t:)"$(printf 'foo bar\t\tbaz')"}
<foo bar>
<baz>

つまり、コマンド置換を引用符で囲む必要があります。そうしないと、コマンド置換の -splittingの結果として生じるフィールドのs:\t:結合 (の最初の文字を含む) に が適用されます。$IFS$IFS

あるいは、$IFS空の文字列または単一の空白以外の文字に設定することもできます。

$ (IFS=; printf '<%s>\n' ${(ps:\t:)$(printf 'foo bar\t\tbaz')})
<foo bar>
<baz>

答え2

$( foo ) を引用符で囲む必要があります。

fields=( ${(ps:\t:)"$( foo )"} )
echo $#fields

発見できるここにいくつかの良い例を挙げます

答え3

IFS=" "; set -f
a=( $(echo -e "a b\tc d") )
printf '<%s>\n' "size=${#a[@]}" "${a[@]}"

関連情報