Jak rekurencyjnie usunąć podkatalogi i pliki, ale nie pierwszy katalog nadrzędny?

14

Jestem w stanie użyć następujących do usunięcia katalogu docelowego i rekurencyjnie wszystkich jego podkatalogów i zawartości.

find '/target/directory/' -type d -name '*' -print0 | xargs -0 rm -rf

Nie chcę jednak, aby katalog docelowy został usunięty. Jak mogę usunąć tylko pliki z celu, podkatalogów i ich zawartości?

Michael Prescott
źródło

Odpowiedzi:

12

Poprzednia odpowiedź jest prawie poprawna. Nie powinieneś jednak cytować znaków globu powłoki, jeśli chcesz, aby działały. Oto polecenie, którego szukasz:

rm -rf "/target/directory with spaces/"*

Zauważ, że * jest poza podwójnymi cudzysłowami. Ten formularz działałby również:

rm -rf /target/directory\ with\ spaces/*

Jeśli masz *cudzysłowy, jak pokazano powyżej, to będzie on próbował jedynie usunąć pojedynczy plik o nazwie dosłownie *w katalogu docelowym.

pioto
źródło
1
To nie działa z ukrytymi plikami i folderami. Musiałem to zrobić jeszcze raz z
The Unfun Cat
8

Jeszcze trzy opcje.

  1. Używaj findz -mindepth 1i -delete:

    −mindepth poziomy
    Nie stosuj żadnych testów ani działań na poziomach mniejszych niż poziomy (nieujemna liczba całkowita).
    −mindepth 1 oznacza przetwarzanie wszystkich plików oprócz argumentów wiersza poleceń.

    -Usuń
    pliki; true, jeśli usunięcie się powiodło. Jeśli usunięcie się nie powiedzie, zostanie wyświetlony komunikat o błędzie. Jeśli −delete się nie powiedzie, status wyjścia find będzie różny od zera (kiedy w końcu wyjdzie). Użycie -delete automatycznie włącza opcję -depth.
    Przed użyciem tej opcji przetestuj dokładnie opcję -depth.

    # optimal?
    # -xdev      don't follow links to other filesystems
    find '/target/dir with spaces/' -xdev -mindepth 1 -delete
    
    # Sergey's version
    # -xdev      don't follow links to other filesystems
    # -depth    process depth-first not breadth-first
    find '/target/dir with spaces/' -xdev -depth -mindepth1 -exec rm -rf {} \;
    



2. Użyj find, ale z plikami, nie katalogami. Pozwala to uniknąć konieczności rm -rf:

    # delete all the files;
    find '/target/dir with spaces/' -type f -exec rm {} \;

    # then get all the dirs but parent
    find '/target/dir with spaces/' -mindepth 1 -depth -type d -exec rmdir {} \;

    # near-equivalent, slightly easier for new users to remember
    find '/target/dir with spaces/' -type f -print0 | xargs -0 rm
    find '/target/dir with spaces/' -mindepth 1 -depth -type d -print0 | xargs -0 rmdir



3. Śmiało i usuń katalog nadrzędny, ale utwórz go ponownie. Możesz utworzyć funkcję bash, aby to zrobić za pomocą jednego polecenia; oto prosty jednoliniowy:

    rm -rf '/target/dir with spaces' ; mkdir '/target/dir with spaces'
quack quixote
źródło
2

Co powiesz na

rm -rf /target/directory\ path/*

Jeśli mogą istnieć pliki zaczynające się od. w katalogu docelowym.

rm -rf "/target/directory path/*" "/target/directory path/.??*"

Ta sekunda dopasuje wszystko, zaczynając od., Oprócz. i .. Nie powiedzie się na nazwach takich jak .a, ale to nie jest bardzo powszechne. W razie potrzeby można go dostosować, aby obejmował wszystkie przypadki.

KeithB
źródło
Próbowałem obu i nie działają one dla mnie. Być może dzieje się tak, ponieważ w mojej ścieżce katalogu docelowego są spacje? rm -rf '/ target / ścieżka do katalogu / *' Nie powoduje błędu, ale podkatalogi pozostają.
Michael Prescott
Musisz uciec od spacji, używając ukośnika odwrotnego (\) przed spacją lub umieszczając całą nazwę katalogu w cudzysłowach (").
Zedytowałem
Dzięki, próbowałem tego, jak pokazano w poprzednim komentarzu i nadal nie mogę. (Używam OS X, czy to ma znaczenie?)
Michael Prescott
OS X powinien działać dobrze, właśnie tego używam. Upewnij się, że nie używasz zarówno odwrotnego ukośnika, jak i cudzysłowu. Tylko jedno lub drugie.
KeithB
Tak, tylko używając cytatów. Jeśli usunę *, a więc używam tylko rm -rf "/ target / directory path /" katalog „ścieżka katalogu” zostanie usunięty wraz z podkatalogami „ścieżka katalogu”. Jeśli użyję rm -rf "/ target / directory path / *", nic się nie dzieje.
Michael Prescott,
2
find /target/directory/ -xdev -depth -mindepth 1 -exec rm -Rf {} \;
Siergiej
źródło