変数にファイル名パターンを持つxargs rmを探す

変数にファイル名パターンを持つxargs rmを探す

次のコマンド:

find /directory -type f -name "*.txt" -print | xargs rm

ディレクトリとサブディレクトリのすべてのファイルを削除するだけ.txtです。ただし、findたとえば、ファイル拡張子の変数または配列を作成してから、

TXT=(*.txt)
for ii in ${TXT[@]}; do
  find /directory -type f -name $TXT -print | xargs rm
done

このコマンドはサブディレクトリのファイルを削除しません.txt。なぜ?サブディレクトリのファイルを削除するために2番目のコード部分をどのように変更しますか?

PS:ファイル拡張子が複数あり、配列を使用しました。

ベストアンサー1

配列の割り当て、

TXT=(*.txt)

*.txtパターンに一致する現在のディレクトリのファイル名のリストにパターンを展開します。シェルは割り当て時にこれを行います。あなたが望むものではありませんか?次のfindリテラル文字列を提供しようとしています*.txt

pattern='*.txt'
find /directory -type f -name "$pattern" -exec rm {} +

ここでもそれを削除しxargs rmrmすぐに実行を開始しますfind。ほとんどの現在の実装は非標準に置き換えることがfindできます。-delete-exec rm {} +

pattern='*.txt'
find /directory -type f -name "$pattern" -delete

ここでは単一パターンのみを扱うので、ループは必要ありません。また、"$pattern"呼び出し時に引用符がfind重要です。それ以外の場合は、パターンが開始する前に現在のディレクトリで一致するすべてのファイル名に置き換えられますfind

複数モードの場合は、次のようなループを実行できます。

patterns=( '*.txt' '*.tmp' )
for pattern in "${patterns[@]}"; do
    find /directory -type f -name "$pattern" -delete
done

配列割り当ての引用符は、シェルがパターンをファイル名一致パターンとして使用するのを防ぐため、重要です。同じ理由で引用する"${patterns[@]}"ことも同様に重要です。"$pattern"

find別のアプローチは、複数のスキーマがあっても一度だけ呼び出すことです。/directoryディレクトリ階層が大きいと、作業速度が大幅に向上する可能性があります。次のコードは、一連の-nameテストを構築してfindこれを行います。

patterns=( '*.txt' '*.tmp' )

name_tests=( )
for pattern in "${patterns[@]}"; do
    name_tests+=( -o -name "$pattern" )
done

# "${name_tests[@]:1}" removes the initial "-o", which shouldn't be there.
name_tests=( '(' "${name_tests[@]:1}" ')' )

find /directory -type f "${name_tests[@]}" -delete

上記のスクリプトで最後に実行される実際のコマンドは次のとおりです。

find /directory -type f '(' -name '*.txt' -o -name '*.tmp' ')' -delete

...これにより、ファイル名のサフィックスが付いたすべての一般ファイルが削除されます。.txt または .tmpディレクトリ内または下のどこでも可能です/directory

おすすめ記事