Ich suche nach einem Bash-Skript, das in eine Liste von Verzeichnissen aufgenommen wird und alle bis auf die vier zuletzt erstellten Dateien löscht.
Wie kann ich das machen?
Ich suche nach einem Bash-Skript, das in eine Liste von Verzeichnissen aufgenommen wird und alle bis auf die vier zuletzt erstellten Dateien löscht.
Wie kann ich das machen?
Antworten:
ls -t | sed '1,4d' | xargs echo rm
Entfernen echo
Sie das gewünschte Ergebnis, wenn Sie zufrieden sind.
Wenn Sie Dateinamen mit Leerzeichen haben, ist mehr Arbeit erforderlich.
sed '1,4d'
mit tail -n +5
.
ls
?
Möchten Sie die vier neuesten Dateien in jedem Verzeichnis oder die vier neuesten Dateien in JEDEM Verzeichnis behalten?
Um das erste Problem zu lösen, verwenden Sie find, um jedes Verzeichnis aufzulisten, und entfernen dann in jedem Verzeichnis alle bis auf die vier neuesten Dateien. Das ist nicht zu schwer.
Die Lösung des zweiten Problems erfordert etwas mehr Überlegungen, ist aber tatsächlich einfacher zu schreiben.
Grundsätzlich finden Sie jede Datei rekursiv. Rufen Sie den Befehl "stat" auf und geben Sie die Änderungszeit und den Namen der Datei zurück. Sortieren Sie diese absteigend numerisch und überspringen Sie die ersten vier Dateien, die die neuesten sind.
Entfernen Sie dann die führenden Zeitstempel und die resultierende Liste der Dateinamen.
So etwas wie (ungetestet):
#!/bin/bash
find "$@" -type f -print0 \
| xargs -0 stat -c$'%Y\t%n' \
| sort -rn \
| awk -F$'\t' 'NR > 4 {print $2}' \
| while read f; do
echo rm -v "${f}"
done
Dies sollte funktionieren, obwohl Sie das 'Echo' in der while-Schleife entfernen möchten, um es effektiv zu machen. Testen Sie es zuerst sorgfältig!
Mir ist klar, dass dies nicht ganz das ist, wonach Sie fragen, aber für diese Art der Sicherung ziehe ich es vor, die Protokolldateien zu drehen, bevor Sie die neue erstellen. Es ist etwas expliziter und viel einfacher zu codieren:
#!/bin/bash
#Archive old backups
move () {
if [ -e $1 ]
then
echo "Archiving old backups: $1 to $2"
mv -f $1 $2 || echo "FAILED"
fi
}
#Bump each backup +1
rm -rf backup.4
move backup.3.tgz backup.4.tgz
move backup.2.tgz backup.3.tgz
move backup.1.tgz backup.2.tgz
move backup.tgz backup.1.tgz
#Now create today's backup
...
Dieser Befehl sollte funktionieren
find PATH1 PATH2 PATH3 -type f -printf '%T@ %p\n'|sort -nr|tail -n+5|cut -f 2- -d " "|xargs -i rm {}
Wenn Sie nicht möchten, dass der Befehl Dateien rekursiv löscht, fügen Sie die Option -maxdepth 1
zuvor hinzu-type f
Der Befehl druckt rekursiv jede Datei mit ihrem letzten Änderungsdatum ( find PATH1 PATH2 PATH3 -type f -printf '%T@ %p\n'
), sortiert die Liste nach Datum ( sort -nr
) und überspringt dann die ersten vier Einträge ( tail -n+5
). Schließlich wird die Zeitinformation gelöscht ( cut -f 2- -d " "
) und das Ergebnis anschließend an xargs übergeben, das den entsprechenden Befehl rm generiert und ausführt.
Die einfachste Methode:
for d in dir1 dir2 dir3; do
rm -vf `ls -1t $d | head -n-4`
done