zshでスペースを含む要素をリストする


10

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

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

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

回答:


12

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

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

hello world
wibble

次いでfiles=($(ls))設定files3つの要素を含むようにアレイを:helloworldおよびwibble

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

files=("${(@f)$(ls)}")

空の要素を取り除くためfor f in $files[@]、一般的に配列を反復する適切な方法はであることに注意してください$files(ここでは、要素は空にならないので問題ではありません)。

print $f$fで始まり、-バックスラッシュを展開すると、スイッチとして解釈され$fます。を使用するprint -r -- $fprint -rn -- $f、文字列の後に改行を追加したくない場合。


ありがとうございました。はい、lsは単なる例です。現時点では具体的な目標はありませんでした。空白を含む個別の結果が含まれる可能性があるコマンドからリスト要素を引用またはエスケープする方法を知りたいだけです。
Felix

混乱を招くのは、files =( "$ {(@ f)$(ls)}")式の外側の()が@fで必要な理由です。そして、()が外側に表示されている限り、(f)をいじるだけで問題なく動作するようです。
Koobz 2012年

@Koobz 1.外部(…)が必要なのfilesは、それが文字列ではなく配列であるためです(これには、コマンドによる行の連結が含まれ、によって行われた分割が取り消されます(f))。2. foo=$'one\n\nthree', contrast print -rl $ {(f)foo} `およびprint "${(@f)foo}"。二重引用符は、空の行を保持するために必要です。空行は、そこから取得するlsことはできませんが、他のコマンドで発生する可能性があります。
Gilles「SO-悪をやめる」

大変感謝いたします。この狂気に韻や理由はありますか?そこにさえ、混乱しているのは、中間値が連結された文字列である場合、アウター()が個々の単語の文字列を再度分割しないのはなぜですか?これは、例えばルビーやphpの文字列補間のように見えます。
Koobz 2012年

@Koobz空の単語を特別に扱う理由は、長い間忘れられていた古いバージョンのzshとの歴史的な互換性です。自動的に分割されない理由は、これは驚くべき動作であり、多くの場合望ましい動作ではないためです。自動分割は、ユーザーが指示しない限りzshがエミュレートしないBourneシェルの動作です。
Gilles「SO-悪をやめなさい」

2

zshでは、デフォルトで単語分割を実行しないシェルの展開を使用できます。やってみる

for f in /path/to/files/*; do
    print ${f}
done
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.