web-dev-qa-db-ja.com

「検索」出力に基づいてディレクトリを削除するにはどうすればよいですか?

次のコマンドを発行して、.svnディレクトリを見つけます。

find . -name ".svn"

これにより、次の結果が得られます。

./toto/.svn
./toto/titi/.svn
./toto/tata/.svn

ディレクトリとその内容を削除するために、これらのすべての行をrm -frで処理するにはどうすればよいですか?

169
Arnaud

Findは、見つかった一致ごとに-execオプションを使用して引数を実行できます。スペース/改行およびその他の文字を含むパスを正しく処理できるため、これは推奨されるメカニズムです。ディレクトリ自体を削除する前に、ディレクトリの内容を削除する必要があるため、rmコマンドで-rを使用してこれを実現します。

あなたの例では、あなたが発行することができます:

find . -name ".svn" -exec rm -r "{}" \;

-type dチェックを追加することで、.svnという名前のdirectoriesを検索するようにfindに指示することもできます。

find . -name ".svn" -type d -exec rm -r "{}" \;

警告rm -rを使用すると、フォルダとそのすべての内容が削除されるので注意してください。

空のディレクトリだけを含むディレクトリだけでなく、空のディレクトリも削除したい場合、findは-delete-emptyを使用して削除できます。

find . -name ".svn" -type d -empty -delete
213
Drav Sloan

これは、受け入れられた回答方法よりも速いポータブルです。

セミコロンの代わりに+findコマンドターミネータとして使用すると、CPU使用率が最適化されます。 .svnサブディレクトリがたくさんある場合、これは重要です。

find . -name .svn -type d -exec rm -rf {} +

また、1 ここでは中括弧を引用する必要があります。

1 fishシェルを使用しない限り(これはこの返信を書いてから修正されている可能性があります)。

76
jlliagre

gnu find を使用していると仮定すると、-deleteオプション:

find . -name test -delete

覚えやすいです。

29
Chun Yang

私が使用する私のコンピューター上:

find . \( -name dirname -type d \) -exec rm -r '{}' ';'

ディレクトリは削除されますが、エラーが発生します:

find: ‘./dirname’: No such file or directory

ディレクトリごとに。

私のディレクトリは空ではないため、-deleteオプションは機能しません。私はこの動作の理由を発見しました here

  1. findは./ディレクトリの最初のエントリを受け取ります(必須ではありません)。これは、例えばdir.1 /
  2. それをパターン 'dir。?'と比較します。一致しますか?はい。
  3. findは "rm -r dir.1"を実行します。
  4. findは、dir.1 /を入力して、ディレクトリ内のパターンを見つけようとします。 execコマンドについては何も知りません。
  5. dir.1 /はもう見つかりません。 ENOENTを返します(strace出力を見てください)

代わりにこれを使用して回避しました:

rm -r `find . -name dirname -type d`

Findはdirnameという名前のディレクトリに再帰的に再試行することに注意してください。これは実際には必要ではなく、さらに時間がかかります。ディレクトリ構造によっては、--depth findオプションを使用してこれを回避できる場合があります。さらに、dirname/foo/dirnameのようなディレクトリ構造がある場合、rmから「そのようなファイルまたはディレクトリはありません」というエラーが発生します。エラーを抑制するには、stderrを/ dev/nullにリダイレクトするか、rmで-f(強制)フラグを使用します。

13
Samuel

これを行うより速い方法は次のとおりです。

find . -name ".svn" -type d -Prune -exec rm -rf '{}' '+'

別の「.svn」の中に「.svn」がある場合。

12
Chang Yu-heng

Bash固有のソリューション:

shopt -s globstar
rm -r **/.svn
shopt -u globstar #optional. this will disable globstar expansion
5
rush

-deleteアクションが-pathテストでうまく機能することがわかりました。たとえば、以下は元のポスターの問題に取り組むべきです:

find . -path '*/.svn*' -delete
4
Magnus