特定のパターンを含むファイルがあるディレクトリからファイルを削除します。

特定のパターンを含むファイルがあるディレクトリからファイルを削除します。

ランダムに名前が付けられた100個のテキストファイルを含む "/home/ben/files"というディレクトリがあるとします。 100個のテキストファイルの中には、「DELETEME」という単語だけが含まれています。

たとえば、file1.txt、file2.txt、file3.txt、file4.txt、file5.txt...などです。

このパターンを含むファイルを削除するにはどうすればよいですか?

答え1

少なくともGNU grepを使用すると、次のことを試すことができます。

grep -lZr "DELETEME" /home/ben/files | xargs -0 rm

警告:これは/home/ben/filesサブフォルダを介して繰り返されます。これを望まない場合は、より多くの予防措置を講じる必要があります。

(空白の区切り記号の使用を提案したコメントのCasに感謝します。)

答え2

GNUの使用find:

まず、いくつかの設定を行い、ディレクトリを作成し、その中に100個の空のファイルを作成し、それらのいくつかに「DELETEME」を追加します。

mkdir files
touch files/{001..100}
for i in 001 010 020 030 040 050 065 077 088 099 ; do echo "DELETEME" >> files/$i ; done

次に、DELETEMEを含むファイルを一覧表示します。

find ./files/ -type f -exec grep -q DELETEME {} \; -print
./files/050
./files/001
./files/065
./files/020
./files/040
./files/030
./files/088
./files/077
./files/099
./files/010

これにより、trueを返すすべてのファイルが印刷されますgrep -q DELETEME。ここで\;終わることが重要です。-execいいえ +)、各ファイルを個別にテストする必要があるためです。それ以外の場合は、終了コードはgrep -q現在実行されているファイルの完全な配置についてです。

findの述語は基本的にAND演算で一緒に連結されるので、その効果を大まかに英語に翻訳すると「grep ANDは-exec前の項目がtrueを返したすべてのファイルを削除します」です。

これは、シェルメタ文字、改行、その他のスペースを含む有効な文字を含むファイル名に適用されます。

最後に一致を削除するには、-delete代わりに次を使用します-print

find ./files/ -type f -exec grep -q DELETEME {} \; -delete

使用しているバージョンが存在しfindない場合は再利用-deleteできます。-exec

find ./files/ -type f -exec grep -q DELETEME {} \; -exec rm {} +

ファイル名を個別に削除する必要はないので、ここで+2番目のものを使用できます。一括削除する方が良いと高速です。-exec

もちろん、-maxdepth 1再帰を防ぐために find の他の述語を使用することもできます。


しかし、次のファイルを削除するにはただ「DELETEME」、それはすべてです。以下を行う必要があります。

まず、そのようなファイルが 1 つ以上あることを確認します。

$ echo "DON'T DELETEME" > files/001

DELETEMEやその他の内容を含むファイルのリストを印刷します。

$ find ./files/ -type f -exec grep -q '^DELETEME$' {} \; -exec grep -vq '^DELETEME$' {} \; -print
./files/001

この場合、単に正規表現を使用するので^DELETEME$はなく、DELETEMEDELETEMEを含む行だけを一致させ、行内の他の項目は何も一致させないようにしたいからです。行でオプションの先行および/または末尾のスペースを許可するには、次のようにします。^[[:space:]]*DELETEME[[:space:]]*$

次に、それを-exec grepDivideを含む他の一致と組み合わせます^DELETEME$

!2番目のファイルを無効にするには、(boolean NOT)を使用してDELETEMEを含むファイル(他のコンテンツを含むファイルと共に)を一覧表示できます-exec

$ find ./files/ -type f -exec grep -q '^DELETEME$' {} \; ! -exec grep -vq '^DELETEME$' {} \; -print
./files/050
./files/065
./files/020
./files/040
./files/030
./files/088
./files/077
./files/099
./files/010

./files/001私たちが望むファイルがリストにありません。

また、!2番目の述部の前にある内容に注意してください-exec。これは非常に重要で見落としやすいので、明らかにしました。

この例では、最初に-exec grep含まれているファイルのリストをインポートして^DELETEME$から、^ DELETEME $を除くすべてのファイルを含むファイルをANDとして操作しません。

ファイルを-print置き換えたり、-delete実際に削除したりできます。-exec rm {} +


PS:これより複雑な場合は、おそらく次のようにPerlスクリプトを書く傾向があります。ファイル::検索基準寸法。

いくつかはただたくさんブール演算子に連結された述語チェーンを持つ非常に長いコマンドラインを使用するよりも、手続き型言語スタイルで書く方が簡単ですfind(論理チェーンを失いやすい)。

関連情報