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 :-)