Antworten:
Wenn Sie Dateien durchlaufen möchten, verwenden Sie niemalsls
*. tl; dr Es gibt viele Situationen, in denen Sie am Ende die falsche Datei oder sogar alle Dateien löschen würden.
Leider ist dies in Bash eine schwierige Sache. Bei einer noch älteren find_date_sorted
doppelten Frage gibt es eine funktionierende Antwort, die Sie mit kleinen Änderungen verwenden können:
counter=0
while IFS= read -r -d '' -u 9
do
let ++counter
if [[ counter -gt 3 ]]
then
path="${REPLY#* }" # Remove the modification time
echo -e "$path" # Test
# rm -v -- "$path" # Uncomment when you're sure it works
fi
done 9< <(find . -mindepth 1 -type f -printf '%TY-%Tm-%TdT%TH:%TM:%TS %p\0' | sort -rz) # Find and sort by date, newest first
* Nichts für ungut Jungs - ich habe es auch schon mal benutzt ls
. Aber es ist wirklich nicht sicher.
Bearbeiten: Neufind_date_sorted
bei Unit-Tests.
((++counter>3))
als Test. Es ist schön prägnant. Was Oneliner betrifft: Wenn es um Kürze geht, wickeln Sie den Code in eine Funktion ein, und machen Sie sich darüber keine Sorgen.
Um alle bis auf die 3 neuesten Dateien mit einem zsh-Glob zu löschen, können Sie mit Om
(Großbuchstabe O) die Dateien vom ältesten zum neuesten und mit einem Index die gewünschten Dateien abrufen.
rm ./*(Om[1,-4])
# | |||| ` stop at the 4th to the last file (leaving out the 3 newest)
# | |||` start with first file (oldest in this case)
# | ||` subscript to pick one or a range of files
# | |` look at modified time
# | ` sort in descending order
# ` start by looking at all files
Andere Beispiele:
# delete oldest file (both do the same thing)
rm ./*(Om[1])
rm ./*(om[-1])
# delete oldest two files
rm ./*(Om[1,2])
# delete everything but the oldest file
rm ./*(om[1,-2])
Die mit Abstand einfachste Methode besteht darin, zsh und seine Glob-Qualifikationsmerkmale zu verwenden : Om
nach abnehmendem Alter (dh dem ältesten zuerst) zu sortieren und [1,3]
nur die ersten drei Übereinstimmungen beizubehalten.
rm ./*(Om[1,3])
Weitere Beispiele finden Sie unter Wie filtere ich einen Glob in zsh?
Und tun Beachtung l0b0 Rat : Ihr Code brechen schrecklich , wenn Sie Dateinamen, die Shell - Sonderzeichen enthalten.
Mit der folgenden Funktion können Sie die neueste Datei in einem Verzeichnis abrufen:
newest_in()
{
local newest=$1
for f;do [[ $f -nt $newest ]] && newest="$f"; done;
printf '%s\n' "$newest"
}
Geben Sie ihm einen anderen Satz von Dateien, indem Sie nach jeder Iteration die neueste Datei exzudieren.
Tipp: Wenn Sie den ersten Satz von Dateien in einem Array mit dem Namen "$ {files [@]}" speichern, speichern Sie den Index der zuletzt gefundenen Datei und unset 'files[index]'
vor der nächsten Iteration.
Verwendungszweck: newest_in [set of files/directories]
Beispielausgabe:
[rany$] newest_in ./*
foo.txt
[rany$]
Erstens ist die -R
Option die Rekursion, was wahrscheinlich nicht das ist, was Sie wollen - das wird auch in allen Unterverzeichnissen gesucht. Zweitens dient der <
Operator (wenn er nicht als Umleitung angesehen wird) dem Zeichenfolgenvergleich. Sie wollen wahrscheinlich -lt
. Versuchen:
while [ `ls -1A | grep ^- | wc -l` -lt 3 ]
Aber ich würde hier finden:
while [ `find . -maxdepth 1 -type f -print | wc -l` -lt 3 ]
Ich weiß, es ist eine Sünde zu analysieren ls
, aber was ist damit:
find . -type f -maxdepth 1 | xargs ls -ltr | sed '1,3d' | awk '{print $9}' | xargs rm
Ein schneller Test mit 5 leeren Dateien:
$ >1
$ >2
$ >3
$ >4
$ >5
$ find . -type f -maxdepth 1 | xargs ls -lt | sed '1,3d' | awk '{print $9}' | xargs rm
$ ls -1
3
4
5
ls
Ausgabe und Verwenden find
und xargs
Zusammen in der falschen Weise. Wenn Sie kombinieren find
und xargs
ich empfehle Ihnen, find
s -print0
und entsprechend xargs
s -O
Optionen zu verwenden. Weitere Informationen zum Thema finden Sie unter Verwenden von Suchen . Vielleicht möchten Sie auch einen Blick darauf werfen und lesen, warum das Parsen von ls sehr schlecht ist.
Dieser Einzeiler macht alles, was ich denke:
ls -t1 /home/user/test | tail -n +4 | xargs -I{} rm -- "{}"
Hier ist eine Lösung:
rm /appserver/webapplogs/$(ls -t1 /appserver/webapplogs/|tail -1)