Shell-Skript zum Löschen von Verzeichnissen, die älter als n Tage sind

165

Ich habe Verzeichnisse mit folgenden Namen:

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

Wie würde ich die Verzeichnisse, die älter als 10 Tage sind, mit einem Bash-Shell-Skript löschen?

bobsr
quelle
1
Um eine Beziehung zu ihrer tatsächlichen Erstellungs- / Änderungszeit zu haben? Weil findkönnte es tun, ohne auf den Namen zu schauen, dann ...
Wrikken
Sie sollten auch Zeit für die Erstellung / Änderung haben
Bobsr
4
Was meinst du mit "älter als"? Beziehen Sie sich auf die Zeit, zu der das Verzeichnis erstellt wurde, den Zeitpunkt, zu dem der Inhalt zuletzt geändert wurde, oder auf etwas anderes? Seien Sie vorsichtig mit einigen der folgenden Antworten. ctimeist die Inode-Änderungszeit. Bei einem Verzeichnis ändert sich dies, wenn Dateien zum Verzeichnis hinzugefügt oder daraus entfernt werden.
Ajk

Antworten:

389

Dies wird es rekursiv für Sie tun:

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

Erläuterung:

  • find: der Unix-Befehl zum Suchen von Dateien / Verzeichnissen / Links usw.
  • /path/to/base/dir: das Verzeichnis, in dem Sie Ihre Suche starten möchten.
  • -type d: finde nur Verzeichnisse
  • -ctime +10: Berücksichtigen Sie nur diejenigen mit einer Änderungszeit, die älter als 10 Tage ist
  • -exec ... \;: Führen Sie für jedes gefundene Ergebnis den folgenden Befehl aus ...
  • rm -rf {}: rekursiv das Entfernen des Verzeichnisses erzwingen; In diesem {}Teil wird das Suchergebnis aus dem vorherigen Teil ersetzt.

Alternativ können Sie Folgendes verwenden:

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

Was etwas effizienter ist, weil es sich um Folgendes handelt:

rm -rf dir1 dir2 dir3 ...

im Gegensatz zu:

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

wie in der -execMethode.


Mit modernen Versionen find, können Sie die ersetzen ;mit +und es wird das Äquivalent des tun xargsAnruf für Sie, vorbei an so viele Dateien wie auf jeder exec - Systemaufruf passt:

find . -type d -ctime +10 -exec rm -rf {} +
Sampson-Chen
quelle
12
-mtimewar besser für mich, da es eher Inhaltsänderungen als Berechtigungsänderungen überprüft, ansonsten war dies perfekt.
Schnellschaltung
7
Ich denke, dies wird auch das Basisverzeichnis selbst löschen
oder Gal
3
@OrGal du bist absolut richtig. Um dies zu verhindern, verwenden Sie einfach : find /path/to/base/dir/*.
Zloynemec
11
Sie können -maxdepth 1 verwenden, um den Inhalt der Verzeichnisse zu ignorieren
Sam
7
Der effizientere Ansatz kann nach hinten losgehen, wenn Sie zu viele Ordner zum Löschen haben: stackoverflow.com/questions/11289551/… . Aus dem gleichen Grund ist es besser, -mindepth 1(anstatt /path/to/folder/*) das Löschen des Basisordners zu vermeiden .
Ohad Schneider
41

Wenn Sie /path/to/basebeispielsweise alle Unterverzeichnisse unter löschen möchten

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

aber Sie wollen nicht die Wurzel löschen /path/to/base, müssen Sie hinzufügen -mindepth 1und -maxdepth 1Optionen, die nur die Unterverzeichnisse zugreifen/path/to/base

-mindepth 1schließt die Wurzel /path/to/basevon den Übereinstimmungen aus.

-maxdepth 1wird NUR Unterverzeichnisse sofort unter passen /path/to/basewie /path/to/base/dir1, /path/to/base/dir2und , /path/to/base/dir3aber es wird rekursiv nicht Liste Verzeichnisse davon in. Daher werden diese Beispiel-Unterverzeichnisse nicht aufgelistet:

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

und so weiter.

Löschen Sie also alle Unterverzeichnisse, /path/to/basedie älter als 10 Tage sind.

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

findunterstützt den -deleteBetrieb, also:

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

Ich denke, es gibt einen Haken, dass die Dateien auch mehr als 10 Tage älter sein müssen. Nicht versucht, kann jemand in Kommentaren bestätigen.

Die am häufigsten gewählte Lösung fehlt, -maxdepth 0sodass rm -rfnach dem Löschen jedes Unterverzeichnis aufgerufen wird . Das macht keinen Sinn, also schlage ich vor:

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

Die -deleteobige Lösung wird nicht verwendet, -maxdepth 0da findsich das Verzeichnis beschweren würde, dass es nicht leer ist. Stattdessen impliziert -depthund löscht es von unten nach oben.

Ondra Žižka
quelle
Ich kann -deleteArbeiten bestätigen , aber wie Sie sagten, können Sie damit nur leere Verzeichnisse löschen, ähnlich wie rmdir.
CTodea
3

Ich hatte Mühe, dies mit den oben bereitgestellten Skripten und einigen anderen Skripten richtig zu machen, insbesondere wenn Dateien und Ordnernamen Zeilenumbrüche oder Leerzeichen enthielten.

Endlich bin ich auf tmpreaper gestoßen und es hat bisher ziemlich gut für uns funktioniert.

tmpreaper -t 5d ~/Downloads


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

Original Quelle Link

Verfügt über Funktionen wie test, mit denen die Verzeichnisse rekursiv überprüft und aufgelistet werden. Möglichkeit zum Löschen von Symlinks, Dateien oder Verzeichnissen sowie des Schutzmodus für ein bestimmtes Muster beim Löschen

user_v
quelle
2

ODER

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

Aktualisierte, schnellere Version davon:

find /path/to/base/dir/* -mtime +10 -print0 | xargs -0 rm -f
Genial
quelle
2
Dieser kann die maximale Befehlszeilenlänge leicht überschreiten. Siehe xargs --show-limits.
Michael Krupp
2
Funktioniert auch nicht, wenn Dateinamen Leerzeichen oder andere spezielle Shell-Zeichen enthalten.
Martin Tournoij
@Carpetsmoker Kümmert sich das -print0/ -0nicht um die speziellen Shell-Zeichen oder nein?
Mpen
Sie haben Recht, dass die xargsVersion @mpen wird, die erste Zeile jedoch nicht.
Martin Tournoij