ZSH - 特定のパターンを無視してファイルを繰り返します(lsまたはfindなし)。

ZSH - 特定のパターンを無視してファイルを繰り返します(lsまたはfindなし)。

'というタイトルの記事を読みました。「lsの出力を解析しない理由」。ディレクトリ内の各ファイルを繰り返したいのですが、記事では以下が最も基本的で理想的な方法の1つです。

for f in *; do
    echo $f
    # …do stuff
done

私が理解していないことの1つは、私がどのようにできるかということです。特定のファイルとディレクトリを無視しますか?私はZSHを使用していてオンになっていますextendedglob。だから私はこれがうまくいくと思いました:for f in *^.jpg; do…しかし、「*^.jpg」だけをエコーし​​てファイルはありません。

ループを本質的に同じに保ちながら、特定のパターンを除外する機能をどのように持つことができますか?ボーナス質問:globを再帰的に作成できますか?

ベストアンサー1

Zshはファイルを列挙する非常に良い方法を提供します。彼らは記録されていますマニュアルの「ファイル名の生成」からしかし、zshのマニュアルは従うのは簡単ではありません。

デフォルトでは、一致するファイルが存在しない場合はエラーが発生します。これは通常コマンドラインでは望ましいですが、スクリプトではそうではありません。このエラーを無効にするには、スクリプトの先頭にエラーを配置してオンにします。null_globオプション:

setopt null_glob
for x in *; do …

または使用N グローバル予選:

# Reliably iterate over non-dot files
for x in *(N); do …

上記のコードスニペットは、現在のディレクトリに存在しないすべてのファイルを繰り返します。ファイルをクリック。そのようなファイルがないと、ループはまったく実行されません(shとは異なり、ループ本体は解放されたglobで一度実行され、デフォルトの*zsh globでエラーが発生します)。

繰り返しにドットファイルを含めるには、次を開きます。got_globオプションまたはDglob修飾子を使用してください。

# Reliably iterate over all files in the current directory
for x in *(DN); do …

もっと冗長であっても、glob修飾子メソッドを使用することをお勧めします。これは、同じオプションが設定されていないスクリプトにそのスニペットをコピーして貼り付けても同じ方法で動作するためです。

名前に基づいて特定のファイルを除外するには、次を使用できます。グローバルオペレータ ^そして~。これはsetopt extended_globスクリプト²になければなりません(これは.zshrcランタイム環境または1から継承されません)。たとえば、*.jpgファイルを除外するには、*~*.jpgまたは^*.jpg

*^.jpgあなたが書いたものはデフォルトでzshでエラーを引き起こします。印刷されたものが表示されている場合は*^.jpgzshを実行していませんnomatch(デフォルトではオン)これは可能です。そうしないと、実際にはshシェルでスクリプトを実行しています。シェルボーンライン上に。 )

setopt extended_glob
# Iterate over all the files in the current directory except *.jpg and .*
for x in *~*.jpg(N); do …

サブディレクトリを再帰的に移動するのは簡単です。以下を使用してください。**/

setopt extended_glob
# Iterate over all the files in the current directory and its (grand-)*children except *.jpg and .*
for x in **/*~*.jpg(N); do …

渡すグローバル予選、名前以外の基準に基づいてファイルを選択することもできます。たとえば、ディレクトリ、シンボリックリンクなどを除いて通常のファイルのみを繰り返すには、次のようにします。

# Iterate over all regular files in the current directory and its (grand-)*children except *.jpg and .*
for x in **/*(.DN); do …

e任意のコードを実行するか、glob修飾子を使用してファイルを含めるか+どうかを決定することもできます。ただし、forループでワイルドカードパターンを使用する場合は、フィルタリングコードをループ本体の上部に配置する方がはっきりします。

1入力できますがsetopt extended_glob、その内容を想定しているスクリプトは他のコンピュータや別のアカウントで競合する可能性があるため、使用しないことをお勧めし~/.zshenvます.zshenv
。 ²zsh完了機能を作成すると、これらの機能はextended_globオープン環境で実行されます。

おすすめ記事