ランダムに名前が付けられた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$
はなく、DELETEME
DELETEMEを含む行だけを一致させ、行内の他の項目は何も一致させないようにしたいからです。行でオプションの先行および/または末尾のスペースを許可するには、次のようにします。^[[:space:]]*DELETEME[[:space:]]*$
次に、それを-exec grep
Divideを含む他の一致と組み合わせます^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
(論理チェーンを失いやすい)。