サブシェルで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
---
どうやってこれを達成できますか? (マニュアルでこのコンテンツが見つかる場所を示すこともできます。)
答え1
デフォルトの分割演算子($IFS
引用符なしのコマンド置換で実行されるBourneなどの単語分割に加えて)は、パラメータs
拡張フラグを使用します。
array=(${(ps:\n:)"$(cmd)"})
cmd
出力は空の要素(空行)を破棄して改行に分割されます。
p
これらの\x
拡張を有効にすることです。いつものように、ps:\n:
エイリアスは短いです:(f
オンライン分割F種子):
array=(${(f)"$(cmd)"})
空行を維持するには、次のようにします。
array=("${(f@)$(cmd)"})
他のほとんどのシェルと同様に、コマンドの代替バーがみんな末尾の改行文字なので、すべての末尾の空白行です。これを保存するには、次のようにします。
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
拡張は空の要素をスキップします。したがって、ループが必要な場合みんな空の要素を含む要素の場合は、次のことを行う必要があります。
for i ("$array[@]") ...
または
for i ("${(@)array}") ...
いいえ
for i ($array) ...
for i in $array