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?
ctimeto czas zmiany i-węzła. W przypadku katalogu zmienia się po dodaniu lub usunięciu plików z katalogu.
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?
ctimeto czas zmiany i-węzła. W przypadku katalogu zmienia się po dodaniu lub usunięciu plików z katalogu.
Odpowiedzi:
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 {} +
-mtimebyło dla mnie lepsze, ponieważ sprawdza zmiany treści, a nie zmiany uprawnień, w przeciwnym razie było idealnie.
find /path/to/base/dir/*.
-mindepth 1(zamiast /path/to/folder/*).
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
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.
-deletedziała, ale tak jak powiedziałeś, możesz go używać tylko do usuwania pustych katalogów, podobnie jak rmdir.
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
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
xargs --show-limits.
-print0/ nie -0zajmuje się znakami specjalnymi powłoki, czy nie?
xargswersja będzie @mpen, ale pierwsza linia nie.
findmógłbym to zrobić bez patrzenia na nazwę wtedy ...