次のコマンド:
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 rm
てrm
すぐに実行を開始します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
。