サブツリーから空のディレクトリをすべて削除する方法は?

サブツリーから空のディレクトリをすべて削除する方法は?

サブツリーから空のディレクトリをすべて削除する方法は?私は次のようなものを使用しました

find . -type d -exec rmdir {} 2>/dev/null \;

ただし、空のディレクトリのみを含むディレクトリを削除するには、複数回実行する必要があります。また、特にcygwinでは非常に遅いです。

答え1

GNUfindオプションと述語と組み合わせて、このコマンドは次の作業を実行する必要があります。

find . -type d -empty -delete
  • -type dディレクトリに制限
  • -empty制限が空です。
  • -deleteすべてのディレクトリを削除

-depthツリーはリーフから始めてナビゲートされ、暗黙的に指定する必要はありません-delete

答え2

深くネストされたディレクトリが最初に一覧表示されます。

find . -depth -type d -exec rmdir {} \; 2>/dev/null

(リダイレクトはfindforではなくコマンド全体に適用されることに注意してくださいrmdir。forだけをリダイレクトするとrmdir中間シェルを呼び出す必要があるため、かなりの速度低下が発生します。)

rmdirクエリの述語を渡すことで、空でないディレクトリで実行されるのを防ぎます-empty。 GNUはコマンドを実行する直前にディレクトリをテストするので、空のディレクトリを選択します。

find . -depth -type d -empty -exec rmdir {} \;

速度を上げるもう1つの方法はグループ通話ですrmdir。どちらも元のバージョンよりはるかに高速です。特にCygwinではさらにそうです。 2つの間に大きな違いはないと予想されます。

find . -depth -type d -print0 | xargs -0 rmdir 2>/dev/null
find . -depth -type d -exec rmdir {} + 2>/dev/null

どの方法が速いかは、空でないディレクトリの数によって異なります。-empty空のディレクトリのみを含むディレクトリをfind表示しても空ではないため、メソッドを組み合わせてグループ呼び出しを実行することはできません。

別のアプローチは、マルチパスを実行することです。これがより速いかどうかは、ディレクトリ階層全体をfind実行間でディスクキャッシュに保持できるかどうかなど、さまざまな要因によって異なります。

while [ -n "$(find . -depth -type d -empty -print -exec rmdir {} +)" ]; do :; done

またはzshを使用してください。これグローバル予選 F空でないディレクトリと一致するため、/^F空のディレクトリと一致します。空のディレクトリのみを含むディレクトリは簡単に一致させることはできません。

while rmdir **/*(/N^F); do :; done

rmdir空のコマンドラインを受信すると終了します。)

答え3

find . -depth -type d -exec rmdir {} +

この質問に対する最も簡単で標準的な答えです。

残念ながら、ここで提供されている他の答えは、すべてのシステムに存在しないベンダー固有の改善に依存しています。

答え4

find私は特に、次のようにディスクスペースをクリーンアップするときに、通常のコマンドにこれらのエイリアスを使用します。ドッパーグル、ここで重複するエントリを削除すると、空のディレクトリが多くなる可能性があります。

そこに説明があるので、.bashrc後で調整する必要がある場合は忘れないようにしてください。

# find empty directories
alias find-empty='find . -type d -empty'

# fine empty/zero sized files
alias find-zero='find . -type f -empty'

# delete all empty directories!
alias find-empty-delete='find-empty -delete'

# delete empty directories when `-delete` option is not available.
# output null character (instead of newline) as separator. used together
# with `xargs -0`, will handle filenames with spaces and special chars.
alias find-empty-delete2='find-empty -print0 | xargs -0 rmdir -p'

# alternative version using `-exec` with `+`, similar to xargs.
# {}: path of current file
# +: {} is replaced with as many pathnames as possible for each invocation.
alias find-empty-delete3='find-empty -exec rmdir -p {} +'

# for removing zero sized files, we can't de-dupe them automatically
# since they are technically all the same, so they are typically left
# beind. this removes them if needed.
alias  find-zero-delete='find-zero -delete'
alias find-zero-delete2='find-zero -print0 | xargs -0 rm'
alias find-zero-delete3='find-zero -exec rm {} +'

関連情報