web-dev-qa-db-ja.com

ディレクトリ内のすべてのファイルとサブフォルダーを削除する最も速い方法は何ですか?

1つのプログラムで多数のネストされたサブフォルダーが作成されました。コマンドrm -fr *を使用してそれらをすべて削除しようとしました。しかし、それは非常に遅いです。それらをすべて削除するより速い方法はありますか?

18
Lei Hao

それらをそのディレクトリから削除する最も速い方法は、それらをそこから移動することです。その後、バックグラウンドで削除します。

mkdir ../.tmp_to_remove
mv -- * ../.tmp_to_remove
rm -rf ../.tmp_to_remove &

これは、現在のディレクトリがマウントされたパーティションのトップレベルではないことを前提としています(つまり、../.tmp_to_removeが同じファイルシステム上にある)。

--で始まるファイル/ディレクトリ名がある場合は、mvの後の-(ステファンによって編集されたとおり)が必要です。

上記はサブディレクトリを再帰的に処理する必要がないので、ほんの一瞬で現在のディレクトリからファイルを削除します。ファイルシステムからのツリーの実際の削除には時間がかかりますが、それが邪魔にならないため、実際の効率はそれほど重要ではありません。

20
Anthon

rsyncは驚くほど高速でシンプルです。最初に空のディレクトリを作成する必要があります。

mkdir emptydir 
 rsync -a --delete emptydir/yourdirectory /

yourdirectory/は、ファイルを削除するディレクトリです。

17
Rahul

rm -rf *、またはより正確な同等のrm -rf -- *の1つの問題は、シェルが最初に現在のディレクトリ内のすべての(非表示でない)ファイルを一覧表示し、それらを並べ替えてrmに渡すことです。現在のディレクトリにあるファイルが大きいと、不要なオーバーヘッドが追加され、ファイルのリストが大きすぎると失敗する可能性もあります。

通常は、代わりにrm -rf .を使用します(これには、隠しファイルも削除するという利点もあります)。しかし、すべてのPOSIX準拠のものを含むほとんどのrm実装は、これを拒否します。その理由は、一部のシェル(すべてのPOSIXシェルを含む)に、.*グロブの拡張に.および..が含まれるという誤った機能があるためです。つまり、rm -rf .*は現在のディレクトリと親ディレクトリを削除することになるため、rmは、これらのシェルのその誤った機能を回避するように変更されています。

pdksh(および他のForsythシェル派生物)、zsh、またはfishのような一部のシェルには、その誤った機能はありません。 zshにはrmビルトインがあり、これはautoload zsh/filesで有効にできます。これは、zsh.*.が含まれていないか、..rm -rf .で正常に動作するためです。したがって、zshでは、次のことができます。

autoload zsh/files
rm -rf .

Linuxでは、次のことができます。

rm -rf /proc/self/cwd/

現在のディレクトリを空にする、または:

rm -rf /dev/fd/3/ 3< some/dir

任意のディレクトリを空にします。

(末尾の/に注意してください)

GNUシステムでは、次のことができます:

find . -delete

さて、現在のディレクトリにいくつかのエントリしかなく、ファイルの大部分がサブディレクトリにある場合、大きな違いはなく、rm -rf -- *がおそらく最も高速になります。 rm -rf(またはすべてのファイルを削除するもの)は、すべてのディレクトリの内容を読み取り、すべてのエントリでunlink()を呼び出すことになるため、コストがかかることが予想されます。 unlink()自体は、削除されたファイルのiノード、ファイルを含むディレクトリ、および一部のファイルシステムマップやその他の空き領域の変更を伴うため、非常に高価になる可能性があります。

rmfind(少なくともGNU実装)は、すでに各ディレクトリのiノード番号でファイルのリストをソートしており、 ext4ファイルシステムでのパフォーマンス。これは、連続する(または互いに近い)iノードが順番に変更されたときに、基礎となるブロックデバイスへの変更の数を減らすためです。

rsyncは、ファイルを名前順に並べ替えます。名前順が偶数順と一致しない限り(ファイル名の並べ替えられたリストからファイルが作成された場合など)、パフォーマンスが大幅に低下する可能性があります。

場合によってはrsyncの方が高速である理由の1つは、ディレクトリがシンボリックリンクで置き換えられている場合に、間違ったディレクトリに下降する可能性のある競合状態を回避するための安全対策を講じていないように見えることですrmまたはfindのように機能します。

さらに最適化するには:

ディレクトリツリーの最大の深さがわかっている場合は、それをfindに渡すことができます。

find . -maxdepth 3 -delete

これにより、深さ3のディレクトリのコンテンツを読み込もうとするfindを省くことができます。

9

最速はrm -rf dirname。 RedHat6.4で、140520ファイルと9699ディレクトリを持つext3ファイルシステムのスナップショットマウントポイントを使用しました。 rm -rf *は低速です。これは、最上位のディレクトリエントリにlotsのファイルがあり、シェルが拡張中でビジーであることが原因である可能性があります*、追加のreaddirとソートが必要です。ディレクトリを上に移動し、rm -rf dirname/

Method                    Real time    Sys time  Variance (+/-)
find dir -delete          0m8.108s     0m3.668s  0.055s
rm -rf dir                0m7.956s     0m3.640s  0.081s
rsync -delete empty/ dir/ 0m8.305s     0m3.918s  0.029s

ノート:

  • rsyncバージョン:3.0.6
  • rm/coreutilsバージョン:8.4-19
  • find/findutilsバージョン:4.4.2-6
7
Otheus