web-dev-qa-db-ja.com

zshでスペースを含む要素を一覧表示する

この時点で2時間ずっとzshスクリプトを勉強していて、壁にぶつかりました。スペースが含まれている可能性のあるファイルのリストを確認したいと思います。 zshは私が勉強しているものであり、スクリプト化しようとしているタスクではないため、zshである限り、次の例とは完全に異なるアプローチを受け入れることができます。

files=(`ls`)
for f in $files; do
    print $f
done

私は明らかにlsを再作成しているだけではなく、$fループの各反復で、ファイル名全体をキャプチャします。

10
Felix

まず、lsの使用は単なる例であると思います。あいまいであるため、どのシェルでもlsの出力を解析できません。読む これがニュースである場合、ls(1)の出力を解析すべきではない理由 任意のシェルで、ファイルのリストを取得するには、ワイルドカードを使用します。 files=(*)

Zshでは、他のシェルと同様に、 コマンド置換 の結果が空白文字で単語に分割されます(より正確には、IFSの値に従って)。 (他のシェルとは異なり、コマンド置換の結果はzshでのグロビングの影響を受けません。)したがって、lsコマンドの出力が

_hello world
wibble
_

次に、files=($(ls))は、files配列をhelloworldおよびwibbleの3つの要素を含むように設定します。

コマンド置換が二重引用符で囲まれている場合、分割は実行されません。 パラメータ拡張フラグ を使用してカスタム分割を実行できます。 _@_フラグを使用して、分割の結果が配列になることを示します(奇妙なことに、二重引用符で囲まれた文字列であっても、展開を二重引用符で囲む必要があります。つまり、"${(@)…}"です。複数の単語に展開されます)。分割するには、sフラグを使用します。 "${(@s:,:)…}"はコンマで分割します。 fフラグは改行でのみ分割されます。

_files=("${(@f)$(ls)}")
_

_for f in $files[@]_は空の要素を削除するため、一般的に配列を反復する適切な方法は_$files_です(ここでは、要素は空にならないので問題ではありません)。

_print $f_は、_$f_で始まり、_-_の円記号を展開する場合、_$f_をスイッチとして解釈します。文字列の後に改行を追加したくない場合は、_print -r -- $f_または_print -rn -- $f_を使用します。

Zshでは、デフォルトでWord分割を実行しないシェルの拡張を使用できます。試す

for f in /path/to/files/*; do
    print ${f}
done
2
u-punkt