Jak usunąć pliki starsze niż X godzin


191

Piszę skrypt bash, który musi usunąć stare pliki.

Obecnie jest wdrażany przy użyciu:

find $LOCATION -name $REQUIRED_FILES -type f -mtime +1 -delete

Spowoduje to usunięcie plików starszych niż 1 dzień.

Co jednak, jeśli potrzebuję dokładniejszej rozdzielczości tego dnia, powiedzmy, że ma 6 godzin? Czy istnieje przyjemny, czysty sposób na zrobienie tego, na przykład użycie funkcji find i -mtime?

Odpowiedzi:


303

Czy findmasz taką -mminopcję? Dzięki temu możesz przetestować liczbę minut od ostatniej modyfikacji:

find $LOCATION -name $REQUIRED_FILES -type f -mmin +360 -delete

A może spójrz na używanie tmpwatchtej samej pracy. phjr również polecany tmpreaperw komentarzach.


2
Użycie --mmin + X zwraca wszystkie pliki z moim znalezieniem. Moja wina, że ​​nie sprawdziłem tego w pierwszej kolejności, ale to polecenie właśnie usunęło większość mojego katalogu domowego. Dla mnie --mmin -X jest poprawnym argumentem.
brandones

tmpreaper to rozwidlenie tmpwatch. Jest bezpieczniejszy i istnieje jako pakiet debian w dystrybucji. Korzyści w stosunku do find -delete: tmpreaper nie usunie dowiązań symbolicznych, gniazd, fifos ani specjalnych plików
Nadir

Zwróć uwagę, że $ REQUIRED_FILES musi znajdować się w cudzysłowach (podwójne cudzysłowy) i możesz użyć wzorca takiego jak: „ .txt” dla wszystkich plików .txt lub plików rozpoczynających się wzorem: „temp- ”, aby usunąć wszystkie pliki o nazwie temp -
achasinh

@PaulDixon jak zmodyfikować to tak, $LOCATIONa $REQUIRED_FILESmoże obie mają wiele wartości, takich jak: dir1 dir2a *.txt *.tmp?
Enissay,

@Enissay $ LOCATION to pojedynczy katalog. W przypadku wielu rozszerzeń prawdopodobnie będziesz chciał użyć wzorca z -regex - patrz stackoverflow.com/questions/5249779/…
Paul Dixon

9

Możesz skorzystać z tej sztuczki: utwórz plik godzinę temu i użyj -newer fileargumentu.

(Lub użyj, touch -taby utworzyć taki plik).


1
nie ma przełącznika -older (przynajmniej w moim poleceniu find), i to byłoby potrzebne. -newer nie pomaga.
iconoclast

czy możesz podać polecenie dotykowe, które wygeneruje plik w wieku 1 godziny, który będzie działał na komputerach, które nie mogą używać -mmin? (Jeśli korzystasz z Linuksa, -mmin jest dostępny, jeśli nie, to data i inne polecenia również są słabe w porównaniu.)
iconoclast

2
@iconoclast touch -t $(date -d '-1 hour' +%Y%m%d%H%M.00) testTworzy plik, testktóry ma zawsze 1 godzinę.
rovr138

4

Oto podejście, które zadziałało dla mnie (i nie widzę, aby było stosowane powyżej)

$ find /path/to/the/folder -name *.* -mmin +59 -delete > /dev/null

usuwając wszystkie pliki starsze niż 59 minut, pozostawiając nienaruszone foldery.


Lepiej '*.*'użyć pojedynczego cudzysłowu, ponieważ powłoka rozwinie go do rzeczywistych nazw plików zamiast trzymać go jako symbol wieloznaczny finddo rozwiązania. To przerywa findrekurencyjną operację na podkatalogach.
MestreLion,

Należy także pamiętać, że -name '*.*'nie będzie plików Usuń, które nie mają rozszerzenia, takie jak README, Makefileitp
MestreLion

1

Dla SunOS 5.10

 Example 6 Selecting a File Using 24-hour Mode


 The descriptions of -atime, -ctime, and -mtime use the  ter-
 minology n ``24-hour periods''. For example, a file accessed
 at 23:59 is selected by:


   example% find . -atime -1 -print




 at 00:01 the next day (less than 24 hours  later,  not  more
 than one day ago). The midnight boundary between days has no
 effect on the 24-hour calculation.

0

-min jest na minuty.

Spróbuj spojrzeć na stronę podręcznika.

man find

dla więcej typów.


0

Jeśli nie masz „-mmin” w swojej wersji „find”, to „-mtime -0.041667” zbliża się do „w ciągu ostatniej godziny”, więc w twoim przypadku użyj:

-mtime +(X * 0.041667)

więc jeśli X oznacza 6 godzin, to:

find . -mtime +0.25 -ls

działa, ponieważ 24 godziny * 0,25 = 6 godzin


Miałem nadzieję, ponieważ ten stary UNIX nie ma -mmin, ale niestety to nie pomaga, ponieważ ten stary UNIX również nie lubi wartości ułamkowych dla mtime: find: argument na -mtime musi być liczbą całkowitą z zakresu -2147483647 do 2147483647
kbulgrien

0

Oto, co można zrobić, idąc drogą, o której @iconoclast zastanawiał się w swoim komentarzu do innej odpowiedzi.

użyj crontab dla użytkownika lub /etc/crontabdo utworzenia pliku /tmp/hour:

# m h dom mon dow user  command
0 * * * * root /usr/bin/touch /tmp/hour > /dev/null 2>&1

a następnie użyj tego, aby uruchomić polecenie:

find /tmp/ -daystart -maxdepth 1 -not -newer /tmp/hour -type f -name "for_one_hour_files*" -exec do_something {} \;

*/1bo godzina jest zbędna w twoim crontabie. Jest to to samo, co wstawianie * w polu godziny.
colm.anseo

0

find $PATH -name $log_prefix"*"$log_ext -mmin +$num_mins -exec rm -f {} \;


0

Jeśli ktoś findtego nie ma, -mmina jeśli ktoś utknął z wartością, findktóra akceptuje tylko wartości całkowite -mtime, wówczas niekoniecznie wszystko stracone, jeśli weźmie się pod uwagę, że „starszy od” jest podobny do „nie nowszy niż”.

Gdybyśmy byli w stanie stworzyć plik, który ma mime naszego czasu odcięcia, możemy zapytać find o zlokalizowanie plików, które nie są „nowsze niż” nasz plik referencyjny.

Aby utworzyć plik, który ma prawidłowy znacznik czasu jest nieco zaangażowane, ponieważ system, który nie posiada odpowiedniego findprawdopodobnie ma również mniej niż zdolny datepolecenia, które mogą robić takie rzeczy jak: date +%Y%m%d%H%M%S -d "6 hours ago".

Na szczęście inne stare narzędzia, które mogą sobie z tym poradzić, choć w bardziej niewygodny sposób.

Weź pod uwagę, że sześć godzin to 21600 sekund. Chcemy znaleźć czas sprzed sześciu godzin w przydatnym formacie:

$ date && perl -e '@d=localtime time()-21600; \
  printf "%4d%02d%02d%02d%02d.%02d\n", $d[5]+1900,$d[4]+1,$d[3],$d[2],$d[1],$d[0]'
> Thu Apr 16 04:50:57 CDT 2020
202004152250.57

Instrukcja perla przyniosła użyteczną datę, ale należy ją lepiej wykorzystać:

$ date && touch -t `perl -e '@d=localtime time()-21600; \
  printf "%4d%02d%02d%02d%02d.%02d\n", \
  $d[5]+1900,$d[4]+1,$d[3],$d[2],$d[1],$d[0]'` ref_file && ls -l ref_file
Thu Apr 16 04:53:54 CDT 2020
-rw-rw-rw-   1 root     sys            0 Apr 15 22:53 ref_file

Teraz rozwiązaniem dla tego starego systemu UNIX jest coś takiego:

$ find . -type f ! -newer ref_file -a ! -name ref_file -exec rm -f "{}" \;

Dobrym pomysłem może być również wyczyszczenie naszego pliku referencyjnego ...

$ rm -f ref_file
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.