Skrypt powłoki do usuwania katalogów starszych niż n dni


165

Mam katalogi o nazwach:

2012-12-12
2012-10-12
2012-08-08

Jak usunąć katalogi starsze niż 10 dni za pomocą skryptu powłoki bash?


1
Czy mają jakiś związek z faktycznym czasem tworzenia / modyfikacji? Bo findmógłbym to zrobić bez patrzenia na nazwę wtedy ...
Wrikken,

powinny mieć również czas tworzenia / modyfikacji
bobsr

4
Co masz na myśli mówiąc „starszy niż”? Czy odnosisz się do czasu utworzenia katalogu, ostatniej zmiany jego zawartości czy czegoś innego? Uważaj na niektóre z poniższych odpowiedzi; ctimeto czas zmiany i-węzła. W przypadku katalogu zmienia się po dodaniu lub usunięciu plików z katalogu.
ajk

Odpowiedzi:


390

To zrobi to rekurencyjnie:

find /path/to/base/dir/* -type d -ctime +10 -exec rm -rf {} \;

Wyjaśnienie:

  • find: polecenie unixowe do wyszukiwania plików / katalogów / linków itp.
  • /path/to/base/dir: katalog, w którym rozpocznie się wyszukiwanie.
  • -type d: znajdź tylko katalogi
  • -ctime +10: rozważ tylko te, których czas modyfikacji jest starszy niż 10 dni
  • -exec ... \;: dla każdego takiego znalezionego wyniku wykonaj następujące polecenie w programie ...
  • rm -rf {}: rekurencyjnie wymuś usunięcie katalogu; {}część jest, gdy wynik znalezisko zostanie podstawiony do z poprzedniej części.

Alternatywnie użyj:

find /path/to/base/dir/* -type d -ctime +10 | xargs rm -rf

Co jest nieco bardziej wydajne, bo sprowadza się do:

rm -rf dir1 dir2 dir3 ...

w przeciwieństwie do:

rm -rf dir1; rm -rf dir2; rm -rf dir3; ...

jak w -execmetodzie.


Z nowoczesnych wersjach find, można wymienić ;z +i będzie to robić odpowiednikiem xargszaproszenia do Ciebie, przechodząc tyle plików, ile zmieści się na każdym exec wywołania systemowego:

find . -type d -ctime +10 -exec rm -rf {} +

12
-mtimebyło dla mnie lepsze, ponieważ sprawdza zmiany treści, a nie zmiany uprawnień, w przeciwnym razie było idealnie.
quickshift w

7
myślę, że spowoduje to również usunięcie samego katalogu podstawowego
lub Gal

3
@OrGal masz absolutną rację. Aby temu zapobiec, wystarczy użyć: find /path/to/base/dir/*.
zloynemec

11
możesz użyć -maxdepth 1, aby zignorować zawartość katalogów
Sam

7
Bardziej wydajne podejście może przynieść odwrotny skutek, jeśli masz zbyt wiele folderów do usunięcia: stackoverflow.com/questions/11289551/… . Z tego samego powodu, aby uniknąć usunięcia folderu podstawowego, lepiej jest użyć -mindepth 1(zamiast /path/to/folder/*).
Ohad Schneider

41

Jeśli chcesz usunąć wszystkie podkatalogi poniżej /path/to/base, na przykład

/path/to/base/dir1
/path/to/base/dir2
/path/to/base/dir3

ale nie chcesz usuwać katalogu głównego /path/to/base, musisz dodać opcje -mindepth 1i -maxdepth 1, które będą miały dostęp tylko do podkatalogów pod/path/to/base

-mindepth 1wyklucza root /path/to/basez dopasowań.

-maxdepth 1będzie tylko dopasować podkatalogi bezpośrednio pod /path/to/basetakimi jak /path/to/base/dir1, /path/to/base/dir2a /path/to/base/dir3jednak nie będzie lista podkatalogów z nich w sposób rekurencyjnego. Więc te przykładowe podkatalogi nie zostaną wymienione:

/path/to/base/dir1/dir1
/path/to/base/dir2/dir1
/path/to/base/dir3/dir1

i tak dalej.

Tak więc, aby usunąć wszystkie podkatalogi, w /path/to/basektórych są starsze niż 10 dni;

find /path/to/base -mindepth 1 -maxdepth 1 -type d -ctime +10 | xargs rm -rf

19

findwspomaga -deletedziałanie, więc:

find /base/dir/* -ctime +10 -delete;

Myślę, że istnieje haczyk, że pliki muszą być starsze o ponad 10 dni. Nie próbowałem, ktoś może potwierdzić w komentarzach.

Brakuje tutaj rozwiązania z największą liczbą głosów, -maxdepth 0dlatego rm -rfpo usunięciu będzie ono wywoływać każdy podkatalog. To nie ma sensu, więc sugeruję:

find /base/dir/* -maxdepth 0  -type d -ctime +10 -exec rm -rf {} \;

Powyższe -deleterozwiązanie nie używa, -maxdepth 0ponieważ findnarzekałbym, że katalog nie jest pusty. Zamiast tego sugeruje -depthi usuwa od dołu do góry.


Mogę potwierdzić, że -deletedziała, ale tak jak powiedziałeś, możesz go używać tylko do usuwania pustych katalogów, podobnie jak rmdir.
CTodea,

3

Starałem się to naprawić, używając skryptów podanych powyżej i kilku innych skryptów, zwłaszcza gdy nazwy plików i folderów miały nową linię lub spacje.

W końcu natknąłem się na tmpreaper i do tej pory działał on całkiem nieźle.

tmpreaper -t 5d ~/Downloads


tmpreaper  --protect '*.c' -t 5h ~/my_prg

Oryginalny link do źródła

Posiada funkcje takie jak test, który rekurencyjnie sprawdza katalogi i wyświetla je. Możliwość usuwania dowiązań symbolicznych, plików lub katalogów, a także trybu ochrony dla określonego wzorca podczas usuwania


2

LUB

rm -rf `find /path/to/base/dir/* -type d -mtime +10`

Zaktualizowana, szybsza wersja:

find /path/to/base/dir/* -mtime +10 -print0 | xargs -0 rm -f

2
Ten może łatwo przekroczyć maksymalną długość linii poleceń. Zobacz xargs --show-limits.
Michael Krupp

2
Nie zadziała również, jeśli istnieją nazwy plików zawierające spacje lub inne specjalne znaki powłoki.
Martin Tournoij

@Carpetsmoker Czy -print0/ nie -0zajmuje się znakami specjalnymi powłoki, czy nie?
otwarte

Masz rację, że xargswersja będzie @mpen, ale pierwsza linia nie.
Martin Tournoij
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.