サブツリーの空のディレクトリをすべて削除するにはどうすればよいですか?私はのようなものを使いました
find . -type d -exec rmdir {} 2>/dev/null \;
しかし、空のディレクトリのみを含むディレクトリを削除するには、複数回実行する必要があります。さらに、それは特にcygwinの下ではかなり遅いです。
GNU find
オプションと述語を組み合わせると、このコマンドは次のように機能します。
find . -type d -empty -delete
-type d
はディレクトリに制限されます-empty
は空のものに制限されています-delete
は各ディレクトリを削除しますツリーは-depth
に含まれているため、-delete
を指定する必要なしに、葉からウォークされます。
深くネストされたディレクトリを最初にリストします。
find . -depth -type d -exec rmdir {} \; 2>/dev/null
(リダイレクトはfind
だけでなくrmdir
コマンド全体に適用されることに注意してください。rmdir
のみにリダイレクトすると、中間シェル)
空でないディレクトリでrmdir
を実行しないようにするには、-empty
検索する述語。 GNU findは、コマンドを実行しようとしているときにディレクトリをテストするため、空になったばかりのディレクトリが取得されます。
find . -depth -type d -empty -exec rmdir {} \;
速度を上げる別の方法は、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を使用します。 glob qualifierF
は空でないディレクトリに一致するため、/^F
は空のディレクトリに一致します。空のディレクトリのみを含むディレクトリは、それほど簡単に照合することはできません。
while rmdir **/*(/N^F); do :; done
(これは、rmdir
が空のコマンドラインを受け取ると終了します。)
rmdir
に-p
を追加するだけで、1回のパスで機能します。それはかなりまたは最適ではありませんが、すべてを取得する必要があります。これは、削除するディレクトリの空でない親ディレクトリを削除するようにrmdirに指示します。
-empty
テストを追加して検索を少し節約できるので、空でないディレクトリを使用する必要はありません。
find . -depth -type d -exec rmdir {} +
この質問に対する最も簡単で標準に準拠した答えです。
ここに記載されている他の回答は、残念ながらすべてのシステムに存在しないベンダー固有の拡張機能に依存しています。
特にdupegurを使用してディスク領域をクリーンアップする場合は特に、頻繁に使用される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 {} +'
find . -type d -printf "%d %p\n" |\ sort -nr |\ Perl -pe 's/^\d+\s//;' |\ while read dir; do \ (rmdir "$dir" > /dev/null 2>&1); \ done
仕組みは次のとおりです。
rmdir
を1つずつ実行します