再帰的rmdirの効果の実装

再帰的rmdirの効果の実装

私が知っている限り、パラメータにディレクトリだけがあり、ツリーのどこにもファイルがない場合は、パラメータへrmdirの参照を削除するオプションしかありません。-r最も簡単な方法は何ですか?

答え1

GNUfindと現在のBSD find(macOSを含む)には、-deleteこの目的に使用できるタスクがあります。

find . -type d -empty -delete

すべての空のディレクトリを見つけて削除します。これ-deleteにより深度優先処理が有効になるため、他のディレクトリのみが含まれ、サブディレクトリにはファイルが含まれていないディレクトリが削除されます。

答え2

zshシェルを使用して、引数を(サブ)ディレクトリリストに繰り返し展開し、奥行きの逆順に並べ替え、rmdirリストを順次処理できます。各ディレクトリが空の場合にのみ警告で成功します(そしていいえ空でないディレクトリを削除します。これにより、空のディレクトリツリーが削除され、ディレクトリが空でない場合は警告が表示されます。

bydepth機能を借りました。ステファンの答えはここにあります

bydepth() REPLY=${REPLY//[^\/]}
rmdir **/(/O+bydepth)

このbydepth関数は、スラッシュ以外のすべての文字を削除してREPLY変数を(再)設定します。その後、glob修飾子のソート機能は、O+REPLY文字列を使用して最も長いものからソートします。別のglob修飾子は、/ディレクトリのみを選択することです。初期**/ワイルドカードはzshに現在のディレクトリから再帰的に拡張するように指示します。

サンプル実行:

$ : no files exist
$ mkdir -p a/b/c/d
$ find .
.
./a
./a/b
./a/b/c
./a/b/c/d
$ rmdir **/(/O+bydepth)
$ find .
.
$ 
$ : a file exists
$ mkdir -p a/b/c/d
$ touch a/b/c/somefile
$ find .
.
./a
./a/b
./a/b/c
./a/b/c/d
./a/b/c/somefile
$ rmdir **/(/O+bydepth)
rmdir: failed to remove ‘a/b/c/’: Directory not empty
rmdir: failed to remove ‘a/b/’: Directory not empty
rmdir: failed to remove ‘a/’: Directory not empty
$ find .
.
./a
./a/b
./a/b/c
./a/b/c/somefile

関連情報