web-dev-qa-db-ja.com

特定の拡張子を持つすべてのファイルを再帰的に削除します

ディレクトリとそのサブディレクトリにあるすべての* .oファイルを削除したい。ただし、エラーが発生します。

sashoalm@aspire:~/.Workspace.OLD$ rm -r *.o
rm: cannot remove `*.o': No such file or directory

一方、 rm *.oは機能しますが、再帰的ではありません。

197
sashoalm

それは悪いことです:rm -rはファイルを削除するためのものではなく、ディレクトリを削除するためのものです。幸いなことに、おそらく*.oに一致するディレクトリはありません。

zshではshbashでは不可能です(bashの新しいバージョンではこれが可能ですが、shopt -s globstarでシェルオプションglobstarを有効にした場合のみ)。展開パターンは**/*.oですが、これもファイルに限定されません(zshには、ファイル以外を除外するためのトリックもあります)。

しかし、これはむしろfindの場合です。

find . -type f -name '*.o' -delete

または(-deleteがPOSIXかどうかわからないため)

find . -type f -name '*.o' -exec rm {} +
303
Hauke Laging

これは、rm-rスイッチの動作とは異なります。

   -r, -R, --recursive
          remove directories and their contents recursively

rmにはファイル検索機能がありません。その-rスイッチは、ローカルディレクトリに降りて、指定したパターンに一致するファイルを識別しません。代わりに、パターン(*.o)はシェルによって展開され、rmはそのパターンに一致する名前のディレクトリに移動して削除します。名前が.oで終わるディレクトリがある場合、試行したコマンドはそれを削除しますが、サブディレクトリに.oファイルが見つかりません。

あなたがする必要があるのは、findを使用することです:

find . -name '*.o' -delete

または、GNU以外の場合find

find . -name '*.o' -exec rm -r {} \;

または、bashを使用している場合は、 globstar を有効にすることができます。

shopt -s globstar
rm -r -- **/*.o

[〜#〜]注[〜#〜]:3つのオプションはすべて、名前が.oで終わるディレクトリも削除しますあなたが望むものではなく、次のいずれかを使用してください:

find . -type f -name '*.o' -delete
find . -type f -name '*.o' -exec rm {} \;
rm -- **/*.o
62
terdon