私が見る限り、rmdir
にはオプション-r
があり、ディレクトリのみが含まれ、ツリーのどこにもファイルが含まれていない場合にのみ、引数の参照を削除できた可能性があります。それを行う最も簡単な方法は何ですか?
GNU find
、および現在のBSDのfind
(macOSを含む)には-delete
これに使用できるアクション:
find . -type d -empty -delete
空のディレクトリを見つけて削除します。 -delete
アクションは深さ優先処理をアクティブにし、他のディレクトリのみを含み、サブディレクトリにファイルを含まないディレクトリが削除されるようにします。
Zshシェルを使用して、引数を(サブ)ディレクトリのリストに再帰的に展開し、深さで逆ソートすることができます。次に、rmdir
はリストを順番に処理できます。各ディレクトリが空の場合にのみ成功し、空でない場合は警告を表示します(そしてnotディレクトリを削除します)。これにより、空のディレクトリツリーが削除され、ディレクトリが空でない場合に警告が表示されます。
bydepth
関数を ステファンの答えはこちら から借りました。
bydepth() REPLY=${REPLY//[^\/]}
rmdir **/(/O+bydepth)
bydepth
関数は、スラッシュ以外の文字をすべて削除することにより、REPLY変数を(再)設定します。次に、そのREPLY文字列は、glob修飾子O+
の並べ替え関数によって使用され、最も長いものから順に並べられます。他の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