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?
ctime
to 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?
ctime
to 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 -exec
metodzie.
Z nowoczesnych wersjach find
, można wymienić ;
z +
i będzie to robić odpowiednikiem xargs
zaproszenia 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 {} +
-mtime
był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 1
i -maxdepth 1
, które będą miały dostęp tylko do podkatalogów pod/path/to/base
-mindepth 1
wyklucza root /path/to/base
z dopasowań.
-maxdepth 1
będzie tylko dopasować podkatalogi bezpośrednio pod /path/to/base
takimi jak /path/to/base/dir1
, /path/to/base/dir2
a /path/to/base/dir3
jednak 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/base
których są starsze niż 10 dni;
find /path/to/base -mindepth 1 -maxdepth 1 -type d -ctime +10 | xargs rm -rf
find
wspomaga -delete
dział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 0
dlatego rm -rf
po 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 -delete
rozwiązanie nie używa, -maxdepth 0
ponieważ find
narzekałbym, że katalog nie jest pusty. Zamiast tego sugeruje -depth
i usuwa od dołu do góry.
-delete
dział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 -0
zajmuje się znakami specjalnymi powłoki, czy nie?
xargs
wersja będzie @mpen, ale pierwsza linia nie.
find
mógłbym to zrobić bez patrzenia na nazwę wtedy ...