Usuń puste drzewa katalogów (usuwając możliwie jak najwięcej katalogów, ale bez plików)


13

Załóżmy, że mam takie drzewo katalogów:

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

Szukam polecenia takiego, że kiedy wprowadzę:

$ [unknown command] ROOTDIR

Całe drzewo katalogów można usunąć, jeśli nie ma pliku, ale tylko katalogi wewnątrz całego drzewa . Powiedzmy jednak, że w pliku SUBDIR1 znajduje się plik hello.pdf:

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

Następnie polecenie musi usunąć tylko SUBDIR2 i poniżej.


Odpowiedzi:


11

Alexis jest blisko. Co musisz zrobić, to:

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

Spowoduje to najpierw drążenie w dół drzewa katalogów, aż znajdzie pierwszy pusty katalog, a następnie usunięcie go. W ten sposób opróżnianie katalogu nadrzędnego, który zostanie następnie usunięty itp. Spowoduje to pożądany efekt (robię to prawdopodobnie 10 razy w tygodniu, więc jestem pewien, że ma rację). :-)


Dlaczego -depthopcja jest konieczna? find . -type d -empty -exec rmdir "{}" \;powinien również działać .... prawda?
— Abhishek A

4
Zastanów się, czy masz drzewo (tylko katalogi) foo/bar/baz. O ile nie użyjesz -depth, spróbuje foonajpierw usunąć , nie powiedzie się, a skończysz foo/barpo uruchomieniu.
— l0b0,

1
Być może alternatywą jest użycie +zamiast, ;aby partii usunąć katalogi. Ponieważ robisz to w pierwszej kolejności, dzieci będą nadal usuwane przed rodzicami (być może zależy to od twojej wersji rmdir / bash i zależą od rmdir, który nie usuwa niepustych katalogów). Działa to dla mnie w bash na cygwin:mkdir -p a/b/c/d ; find a -depth -type d -exec rmdir {} +
— idbrii

4
Ludzie, idźcie do bardziej zwięzłej odpowiedzi go2null poniżej! Nie mogę zrozumieć, dlaczego SE nadaje pierwszeństwo zaakceptowanym odpowiedziom zamiast odpowiedzi z większością głosów poparcia w wyświetlaniu odpowiedzi poniżej pytania. OP akceptuje najlepszą dostępną odpowiedź w swoim momencie wyboru, ale później mogą przyjść znacznie lepsze odpowiedzi, które społeczność komentuje, prawda? (Oczywiście, to jest coś dla meta ...)
— jamadagni

to nie działa dla mnie. usuwa tylko najgłębszy liść (w tym przypadku SUBDIR3)
— Joey Baruch,

24
find ROOTDIR -type d -empty -delete

taki sam jak

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

ale używa wbudowanej akcji „-delete”.

Zauważ, że „-delete” oznacza „-depth”.


Wyrazy uznania za najbardziej zwięzłą odpowiedź za pomocą wbudowanego usuwania funkcji find! Dodaję to do moich lokalnych skryptów narzędzi!
— jamadagni

3

Spróbowałbym tego:

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

1

Oto niektóre wymagania, zanim będziemy mogli to zrobić bezpiecznie:

  1. najpierw usuń podkatalogi, a następnie katalogi wyższego poziomu, tzn. musimy posortować listę katalogów lub użyć flagi rmdir --parents
  2. uruchamiaj ROOTDIR zawsze z / lub ./, aby uniknąć niespodzianek z plikami zaczynającymi się od -
  3. użyj zakończonej NUL listy katalogów do pracy z nazwami katalogów ze spacjami

Oto jak zrobiłbym to w powłoce:

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

Jeśli nie przeszkadzają ci jakieś zbędne błędy, możesz po prostu wymusić usunięcie wszystkich katalogów z rodzicami i nie musisz przeprowadzać żadnego sortowania (nie możesz sortować NUL zakończonych ciągów, co dodaje konieczność tr)

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

Wyrazy uznania za szczegółowe wyjaśnienie Twojej odpowiedzi. Prawdopodobnie zastosowałbym to samo podejście, dopóki nie dowiedziałem się o -empty -deleteopcjach odpowiedzi findw @ go2null.
— Davor Cubranic

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

5
To nie zadziała, jeśli którakolwiek z nazw katalogów zawiera białe znaki lub znaki globowania. Generalnie złym pomysłem jest stosowanie podstawiania poleceń na liście nazw plików. Jest to szczególnie zły pomysł z findponieważ findma sposób, aby wykonać obróbkę czysto: find … -exec.
— Gilles 'SO - przestań być zły'

Dzięki Gillesowi za zwrócenie na to uwagi. @lanzz, zwykle publikowanie tylko polecenia bez wyjaśnienia, co robi (w tym przypadku pułapki) nie wystarczy. Dodaj do swojej odpowiedzi.
— n0pe

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.