サブシェルからzsh配列をインスタンス化したい
_myarray=($(somecommand)
_
欲しいものを受け取ったかどうかを確認します
_for element in $myarray ; do echo "===" ; echo $element ; echo "---" ; done
_
デフォルトでは、要素を区切るために空白(スペースと改行)が使用されています。
また、${(s:-:)"$(somecommand)"}
を使用して_-
_で区切ることができることもわかりました。この場合、スペースと改行は要素を分割しません(つまり、配列要素に改行を含めることができます)。
これまでのところ、改行でのみ分割できません。つまりsomecommand
が返す場合
_Alice
Bob
Arthur C Clarke
Neo
Thomas Anderson
_
上記のfor
ループを印刷してください:
_===
Alice
---
===
Bob
---
===
Arthur C Clarke
---
===
Neo
---
===
Thomas Anderson
---
_
どうすればそれを達成できますか? (そして、おそらくそれをマニュアルのどこに参照するかへのポインタ。)
ネイティブの分割演算子(引用符で囲まれていないコマンド置換で実行されるBourneのような$IFS
Word分割の横)は、s
パラメータ展開フラグを使用します。
array=(${(ps:\n:)"$(cmd)"})
cmd
の出力を改行で分割し、空の要素(空の行)を破棄します。
p
は、これらの\x
拡張を有効にするためのものです。 ps:\n:
は一般的なものなので、エイリアスは短くなります:f
(行で分割するにはf eeds):
array=(${(f)"$(cmd)"})
空の行を保持するには、次のようにします。
array=("${(f@)$(cmd)"})
ここで、他のほとんどのシェルと同様に、コマンド置換はallで後続の改行文字を削除するため、後続のすべての空行が削除されることに注意してください。それらを保存するには、次のようにします。
array=("${(f@)$(cmd; echo .)}")
array[-1]=() # remove that last line added by echo .
$IFS
で単語分割:
IFS=$'\n'
array=($(cmd)) # removes empty lines. Note that contrary to other
# Bourne-like shells, zsh doesn't do globbing there
# so you don't need the "set -o noglob"
IFS=$'\n\n' # like in ksh93, doubling an IFS-whitespace character
# removes its special treatment as a whitespace character
array=($(cmd)) # preserves empty lines except the trailing ones
IFS=$'\n\n'
array=($(cmd; echo .)); array[-1]=() # preserves all empty lines.
$IFS
をグローバルに変更しないようにするには、無名関数で上記を実行できます。
(){
local IFS=$'\n\n'
array=($(cmd; echo .)); array[-1]=()
}
また、$array
展開は空の要素をスキップすることに注意してください。したがって、空の要素を含むall要素をループしたい場合は、次のものが必要です。
for i ("$array[@]") ...
または
for i ("${(@)array}") ...
ない
for i ($array) ...
for i in $array