Entrümpeln mit find, grep und gawk

chris Juni 09, 2015 #grep #gawk #find #cleanup #entrümpeln

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.

Beispiel:

Ist die Datei /home/user/Downloads/test.txt eine Leiche, so wird die Leichenzahl für

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

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