web-dev-qa-db-ja.com

Linuxでは、文字列を含むすべてのファイルを検索して削除するにはどうすればよいですか?

文字列fooを含むすべてのファイルを削除します。 Linuxでbashを使用してこれを行うにはどうすればよいですか?

17
Kitsos

安全な方法は次のとおりです。

grep -lrIZ foo . | xargs -0 rm -f --
  • -lは、検索パターンに一致するファイルのファイル名を出力します。
  • -rは、指定されたディレクトリ.でパターンfooを再帰的に検索します。これが機能しない場合は、-Rをお試しください。
  • -I(大文字のi)を使用すると、PDFなどのバイナリファイルがスキップされます。
  • -Zは、空白を含む名前が誤った方法で解釈されないように(つまり、1つではなく複数の名前として)、ファイル名がゼロ(つまり、nul-)で終了することを保証します。
  • xargs -0は、ファイル名をgrepからrm -fまでフィードし、単語をゼロ(nul)バイトで区切ります(grep-Zオプションを思い出してください)。
  • --はしばしば忘れられますが、オプションの終わりをマークし、名前が-で始まるファイルの削除を許可することは非常に重要です。

削除されるファイルを確認する場合は、| xargs -0 rm -f --の部分を削除し、Zオプションをgrepにしないでください。

別のユーザーが次のようなものを提案しました。これは安全でないため、(実行しないでください)です。

files=`grep foo * | cut -d: -f1`
rm -f $files         # unsafe, do not run it!

削除したくないファイルImportantStufffooを含むobsolete ImportantStuffがある場合、ImportantStuffを失います(そしてnotobsolete ImportantStuff!)このコマンドを実行すると、解釈されたときに$filesがスペースで分解されるためです。このようにファイル名のリストをスカラーシェル変数に入れるのは危険です。

33
Lekensteyn
$ find -type f -exec grep -q "foo" {} \; -exec echo rm -- {} \;

これにより、fooを含むファイルが再帰的に検索されます。二番目 -execは、最初のexecが正常に終了した場合、つまりgrepが一致した場合にのみ実行されます。出力が正しいと思われる場合は、ドライランしてechoを削除します。

または代わりに

$ find -type f -exec grep -q "foo" {} \; -print

そして

$ find -type f -exec grep -q "foo" {} \; -delete

lekensteynによって提案されたように。

17

私はエイドリアンの言うことをします、

しかし、「食品」を含むファイルを誤って削除しないように、fooの前後にWordの境界を追加します(食品を含むすべてを削除するのが目的のものでない限り)。

 $ find -type f -exec grep -q "\<foo\>" {} \; -delete

実際には、削除する前に出力をリダイレクトするので、削除する前に確認できます。

 $ find -type f -exec grep -q "\<foo\>" > /tmp/list_of_files_to_delete
1
Petter H