空のディレクトリツリーを削除する(できるだけ多くのディレクトリを削除するが、ファイルは削除しない)


12

次のようなディレクトリツリーがあるとします。

ROOTDIR
    └--SUBDIR1
        └----SUBDIR2
            └----SUBDIR3

私が入力したときのようなコマンドを探しています:

$ [unknown command] ROOTDIR

ファイルがなく、ツリー全体の内部にのみディレクトリがある場合、ディレクトリツリー全体を削除できます。ただし、SUBDIR1の下にhello.pdfというファイルがある場合は、次のようにします。

ROOTDIR
    └--SUBDIR1
        └--hello.pdf
        └----SUBDIR2
            └----SUBDIR3

次に、コマンドはSUBDIR2以下のみを削除する必要があります。


回答:


11

アレクシスは近いです。あなたがする必要があるのはこれです:

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

最初に空のディレクトリが見つかるまでディレクトリツリーをドリルダウンし、次に削除します。したがって、親ディレクトリを空にしてから削除します。これにより、目的の効果が得られます(おそらくこれは週に10回行うので、間違いないと思います)。:-)


なぜ-depthオプションが必要なのですか?find . -type d -empty -exec rmdir "{}" \;動作するはずです...
アビシェークA

4
ツリーがあるかどうかを検討してください(ディレクトリのみ)foo/bar/baz。を使用しない限り-depthfoo最初に削除しようとして失敗し、foo/bar実行後に終了します。
l0b0

1
+代わりに、代わりにを使用して;、ディレクトリをバッチで削除することもできます。深さ優先で行うため、子は親の前に削除されます(おそらくrmdir / bashのバージョンに依存し、空でないディレクトリを削除しないrmdirに依存します)。これはcygwinでbashで動作します:mkdir -p a/b/c/d ; find a -depth -type d -exec rmdir {} +
idbrii

3
皆さん、以下のgo2nullのもっと簡潔な答えをご覧ください!SEが質問の下に回答を表示する際に最も賛成の回答よりも受け入れられた回答を優先する理由を理解できません。OPは、選択した時点で利用可能なベストアンサーを受け入れますが、後で、より良いアンサーが来る可能性があります。(もちろん、これはメタのためのものです...)
jamadagni 14

これは私には機能しません。それだけで(この場合はSUBDIR3)deepmost葉を削除
ジョーイバルーク

23
find ROOTDIR -type d -empty -delete

と同じ

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

ただし、組み込みの「-delete」アクションを使用します。

「-delete」は「-depth」を意味することに注意してください。


findの組み込みの削除機能を使用して、最も簡潔な回答をしてください これをローカルutilscriptsに追加しています!
jamadagni 14


1

安全に実行する前の要件を次に示します。

  1. 最初にサブディレクトリを削除し、次に上位レベルのディレクトリを削除します。つまり、ディレクトリリストをソートするか、rmdir --parentsフラグを使用する必要があります
  2. 開始ROOTDIRをして、常に/または./で始まるファイルと驚きを避けるために-
  3. NULで終了するディレクトリのリストを使用して、スペースを含むディレクトリ名を操作します

シェルでこれを行う方法は次のとおりです。

find ./ROOTDIR -type d | sort -r | tr '\n' '\000' | xargs -0 rmdir --ignore-fail-on-non-empty

いくつかの冗長なエラーを気にしない場合は、親を持つすべてのディレクトリを強制的に削除することができ、ソートを行う必要はありません(trを追加するNUL終了文字列をソートすることはできません)

find ./ROOTDIR -type d -print0 | xargs -0 rmdir --ignore-fail-on-non-empty --parents

あなたの答えの詳細な説明については賞賛。@ go2nullの回答で-empty -deleteオプションについて学ぶまでは、おそらく同じアプローチを使用していたでしょうfind
デイヴァーCubranic

0
rmdir $(find ROOTDIR -type d | sort -r)

5
ディレクトリ名のいずれかに空白文字またはグロビング文字が含まれている場合、これは機能しません。一般的に、ファイル名のリストでコマンド置換を使用することはお勧めできません。処理をきれいに行う方法があるfindため、特に悪い考えfindですfind … -exec
ジル 'SO-悪であるのをやめる'

それを指摘してくれたGillesに感謝します。@lanzzは、通常、コマンドの実行内容(およびこの場合の落とし穴)を説明せずにコマンドを投稿するだけでは不十分です。回答に追加してください。
n0pe

0

私はこれをします:

find ROOTDIR -type d | xargs -0 -I {} rmdir {}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.