私は多数のファイルを含むいくつかのディレクトリを持っています。特定の文字列は含まれ、他の文字列は含まれていないファイルを削除してこれらのディレクトリをクリーンアップしたいと思います。
たとえば、ファイル名に「AAA」が含まれているが「BBB」、「CCC」、または「DDD」は含まれていないファイルを削除します。
可能ですか?
答え1
find
削除するファイルを再帰的に検索するいくつかの最上位ディレクトリで、次のものを使用します。
find . -type f -name '*AAA*' ! -name '*BBB*' ! -name '*CCC*' ! -name '*DDD*' -print
上記のコマンドは、現在のディレクトリ内または下のすべての一般的なファイルを探します。その中で、名前に を含むファイルを選択し、名前に 、 または を含むファイルの選択を解除しAAA
(それぞれの直後のテストを否定する)、まだ選択したファイルのパス名を印刷します。BBB
CCC
DDD
!
ここで使用されるパターンは、一般的なファイル名一致パターンです(正規表現ではありません)。現在のディレクトリで名前が誤って一致するのを防ぐには、引用符で囲む必要があります。
ファイルを削除するに-print
はに変更します-delete
。
-delete
非標準述部(通常は実装されている述語にもかかわらず)なので、使用する方が移植-exec rm {} +
性が高くなります。これにより、rm
選択したファイルをできるだけ一度に実行できます。
bash
通常、シェルを想定し、ファイル名がインクルードパターンと一致し、除外パターンと一致しないと仮定すると、インクルードおよび除外するパターンのリストが2つあります。
include=( '*AAA*' '*123*' )
exclude=( '*BBB*' '*CCC*' '*DDD*' )
or_filter=()
and_filter=()
for pattern in "${include[@]}"; do
or_filter+=( -o -name "$pattern" )
done
or_filter=( "${or_filter[@]:1}" ) # remove initial -o
for pattern in "${exclude[@]}"; do
and_filter+=( ! -name "$pattern" )
done
find . -type f \( "${or_filter[@]}" \) "${and_filter[@]}" -print