Nachdem gestern der Ubuntu-Upgrade-Prozess (mal wieder) die Ubuntu Installation auf meinem alten Laptop zerschoss, hatte ich vor der Neuinstallation noch Gelegenheit, Sicherungen der wichtigsten Ordner anzulegen. Dabei stellte ich fest, dass die Ordner viel gröĂer waren, als erwartet und dies ĂŒberwiegend bedingt durch ĂŒberflĂŒssige Dateien, die ich ewig nicht mehr angerĂŒhrt hatte.
Mich packte der AufrĂ€umwahn und ich suchte nach einem simplen Tool, welches mir anzeigt, in welchen Ordnern ich am meisten Dateileichen liegen habe. Diese Dateien wĂŒrde ich dann von der Sicherung ausschlieĂen und löschen.
Dateileichen = Dateien, vor Ewigkeiten heruntergeladen, und seitdem nie wieder angefasst. Das heiĂt, access_time(Leiche) < now â x_days
Diese Leichen möchte ich finden, um sie hinterher (nach manueller ĂberprĂŒfung) zu löschen. Meist sind das verhaltete Installationsdateien irgendwelcher Software (die ich meist gar nicht mehr benötige) oder Ergebnisse alter abgeschlossener Analysen. Im Allgemeinen, oft jede Menge Schrott, den ich bedenkenlos löschen kann.
Whitelist
Manchmal sind es jedoch auch Dateien/Ordner, die ich gerne fĂŒr spĂ€ter aufheben wĂŒrde (âes kann ja sein, dass man es nochmal brauchtâ â hehehe). Das bedeutet, ich möchte eine Whitelist mit Dateien und Ordnern fĂŒhren, die ich von der Suche per se ausschlieĂe, da ich sie fĂŒr wichtig erachte.
Verzeichnis-Gruppierung
AuĂerdem stellte ich schnell fest, dass die Ăbersichtlichkeit schnell flöten geht, wenn ich einfach alle solche Dateien nach STDOUT schreibe. Daher wollte ich die Dateien nach Verzeichnis gruppieren und pro Verzeichnis nur die Anzahl solcher Leichen ausgeben.
Da ich im Netz nur spartanische Skripte ohne Whitelist FunktionalitÀt gefunden hab, hab ich kurzerhand selbst ein kleines Bash Skript geschrieben, basierend auf find, grep und gawk.
- ZunÀchst sucht find im angegebenen Verzeichnisbaum nach allen Dateien (nicht Ordnern), auf die mindestens seit x Tagen nicht zugegriffen wurde.
- Dann testet grep, welche dieser Dateien gegen mindestens eins der Whitelist-Pattern matched und filtert diese heraus.
- SchlieĂlich ist gawk fĂŒr das Gruppieren der Leichen pro Verzeichnis zustĂ€ndig. Hierzu iteriert es ĂŒber jede Dateileiche, und erhöht fĂŒr jedes seiner Oberverzeichnisse bis hin zu root die Leichen-Zahl um eins.
Beispiel:
Ist die Datei /home/user/Downloads/test.txt eine Leiche, so wird die Leichenzahl fĂŒr
//home/home/user/home/user/Downloads
je um eins erhöht. Am Ende schreibt gawk die Counts pro Verzeichnis sortiert nach Verzeichnis nach STDOUT.
Das Skript
#! /bin/bash
[ $# == 2 ] || (echo "Two arguments expected" && exit)
printf "Finding subfolders in %s with files not accessed at least %d days\n" $1 $2
touch ausmisten.whitelist
# look for files in given folder which are older than given number of days
find $1 -atime +$2 -type f > ausmisten.result
# filter files based on whitelist
grep -vf ausmisten.whitelist ausmisten.result > ausmisten.filtered
# print number of such files per folder
printf "#files\tIn Directory\n"
gawk ' BEGIN{OFS="\t"} { i=0; while((newPos = index(substr($0,i+1),"/")) && newPos > 0) { i=i+newPos; counts[substr($0,1,i)]++; }; } END{ asorti(counts,sorted); for (i = 1; i <= length(counts); i=i+1) { elem = sorted[i]; print counts[elem],elem } }' ausmisten.filtered
Argumente des Skripts sind
- das Base-Verzeichnis in dem gesucht werden soll
- die Anzahl Tage, die der letzte Zugriff auf eine Datei zurĂŒckliegen muss, sodass sie als Leiche betrachtet wird.
Die Whitelist Datei befindet sich im gleichen Verzeichnis wie das Skript und enthÀlt pro Zeile einen absoluten Pfad:
/.
/usr/
/opt/
Die erste Zeile bewirkt, dass keine versteckten Ordner/Dateien betrachtet werden. AuĂerdem ist es wichtig, die Ordner mit einem endenden / anzugeben, da ansonsten Ordner die nur einen zusĂ€tzlichen Postfix haben ebenfalls ausgeschlossen werden: /home/user/test wĂŒrde auch den Ordner /home/user/test2 ausschlieĂen.
In meinem Download-Verzeichnis findet das Skript mit sh ausmisten.sh /home/USERNAME/Downloads 100 die folgenden Leichen (lÀnger als 100 Tage kein Zugriff):
Finding subfolders in /home/USERNAME/Downloads with files not accessed at least 100 days
# files In Directory
53 /
53 /home/
53 /home/USERNAME/
53 /home/USERNAME/Downloads/
10 /home/USERNAME/Downloads/RRW/
1 /home/USERNAME/Downloads/RRW/META-INF/
28 /home/USERNAME/Downloads/freduce/
3 /home/USERNAME/Downloads/freduce/R.packages/
25 /home/USERNAME/Downloads/freduce/bin/
2 /home/USERNAME/Downloads/gecko-1.2.1/
2 /home/USERNAME/Downloads/kual/
4 /home/USERNAME/Downloads/ncbi-blast-2.2.29+/
2 /home/USERNAME/Downloads/ncbi-blast-2.2.29+/bin/
1 /home/USERNAME/Downloads/ncbi-blast-2.2.29+/doc/
Dieses Skript fĂŒhre ich nun einmal wöchentlich aus, sodass ich regelmĂ€Ăig ausmiste und beim nĂ€chsten Backup nicht wieder vor einem Berg von unnötigen Dateien stehe :-)