Lösung ohne Probleme mit "ls" (seltsam benannte Dateien)
Dies ist eine Kombination aus der Antwort von Ceving und Anubhava. Beide Lösungen funktionieren bei mir nicht. Da ich nach einem Skript suchte, das jeden Tag zum Sichern von Dateien in einem Archiv ausgeführt werden sollte, wollte ich Probleme mit ls vermeiden (Jemand könnte eine komisch benannte Datei in meinem Sicherungsordner gespeichert haben). Also habe ich die genannten Lösungen an meine Bedürfnisse angepasst.
Meine Lösung löscht alle Dateien, außer die drei neusten Dateien.
find . -type f -printf '%[email protected]\t%p\n' |
sort -t $'\t' -g |
head -n -3 |
cut -d $'\t' -f 2- |
xargs rm
Einige Erklärungen:
find listet alle Dateien (nicht Verzeichnisse) im aktuellen Ordner auf. Sie werden mit Zeitstempel ausgedruckt.
sort sortiert die Zeilen nach Zeitstempel (älteste oben).
head druckt die obersten Zeilen bis zu den letzten 3 Zeilen.
cut entfernt die Zeitstempel.
xargs läuft rm für jede ausgewählte Datei.
Damit Sie meine Lösung überprüfen können:
(
touch -d "6 days ago" test_6_days_old
touch -d "7 days ago" test_7_days_old
touch -d "8 days ago" test_8_days_old
touch -d "9 days ago" test_9_days_old
touch -d "10 days ago" test_10_days_old
)
Dadurch werden im aktuellen Ordner 5 Dateien mit unterschiedlichen Zeitstempeln erstellt. Führen Sie zuerst dieses Skript aus und dann den Code zum Löschen alter Dateien.
Dies listet alle Dateien außer den neuesten drei auf:
ls -t | tail -n +4
Dadurch werden diese Dateien gelöscht:
ls -t | tail -n +4 | xargs rm --
Dies listet auch dotfiles auf:
ls -At | tail -n +4
und mit dotfiles löschen:
ls -At | tail -n +4 | xargs rm --
Aber Achtung:ls parsen kann gefährlich sein, wenn die Dateinamen komische Zeichen wie Zeilenumbrüche oder Leerzeichen enthalten. Wenn Sie sicher sind, dass Ihre Dateinamen keine komischen Zeichen enthalten, dann parsen Sie ls ist ziemlich sicher, umso mehr, wenn es sich um ein einmaliges Skript handelt.
Wenn Sie ein Skript zur wiederholten Verwendung entwickeln, sollten Sie die Ausgabe von ls auf keinen Fall parsen und verwenden Sie die hier beschriebenen Methoden:http://mywiki.wooledge.org/ParsingLs
ls -t | tail -n +4 | xargs -I {} rm {}
Wenn Sie einen Einzeiler wünschen
Das Folgende sieht etwas kompliziert aus, ist aber sehr vorsichtig, um korrekt zu sein, selbst bei ungewöhnlichen oder absichtlich böswilligen Dateinamen. Leider erfordert es GNU-Tools:
count=0
while IFS= read -r -d ' ' && IFS= read -r -d '' filename; do
(( ++count > 3 )) && printf '%s\0' "$filename"
done < <(find . -maxdepth 1 -type f -printf '%[email protected] %P\0' | sort -g -z) \
| xargs -0 rm -f --
Erläuterung, wie das funktioniert:
- Suchen gibt
<mtime> <filename><NUL>aus für jede Datei im aktuellen Verzeichnis. sort -g -zführt eine allgemeine numerische Sortierung (Gleitkomma, im Gegensatz zu Ganzzahlen) basierend auf der ersten Spalte (Zeiten) durch, wobei die Zeilen durch NULs getrennt sind.- Die erste
readimwhileloop entfernt die mtime (wird nachsortnicht mehr benötigt fertig). - Der zweite
readimwhileSchleife liest den Dateinamen (läuft bis zur NUL). - Die Schleife erhöht einen Zähler und überprüft ihn dann; Wenn der Status des Zählers anzeigt, dass wir das anfängliche Überspringen überschritten haben, geben wir den Dateinamen aus, getrennt durch eine NUL.
xargs -0hängt dann diesen Dateinamen an die argv-Liste an, die es sammelt, umrmaufzurufen mit.