
Ich möchte eine bestimmte Anzahl der größten Dateien in einem Verzeichnis löschen.
Die Dateinamen der ersten zehn kann ich wie folgt abrufen:
ls -S | head
(oder eine umfangreichere, wenn auch komplexer zu analysierende Version ls -lS | head
)
Wie würde ich diese an rm übergeben? Über xargs?
Würde das also ls -S | head | xargs rm
funktionieren (auch mit Dateinamen mit Leerzeichen usw.?)
Gibt es einen besseren/sichereren Weg?
Es tut mir leid, aber ich konnte das nicht selbst testen, weil ich Angst hatte, etwas zu vermasseln (das Verzeichnis enthält Sachen, die ich wirklich nicht löschen möchte).
Ich verwende macOS.
Antwort1
Würde das also
ls -S | head | xargs rm
funktionieren (auch mit Dateinamen mit Leerzeichen usw.?)
Nein. xargs
standardmäßig wird bei jedem Leerzeichen geteilt, nicht nur bei Zeilenumbrüchen. Und das können Sie bei nicht sehen | xargs echo
, da echo
alle Argumente durch Leerzeichen getrennt gedruckt werden. (Etwas wie | xargs printf "%s\n"
würde sie durch Zeilenumbrüche getrennt drucken, sodass Sie sehen, ob die Teilung in der Mitte eines Dateinamens erfolgt.)
Zumindest GNU xargs muss -d '\n'
nur bei Zeilenumbrüchen teilen, und viele Versionen von xargs müssen -0
bei NUL-Zeichen teilen (das geht mit find -print0
). Sie werden zumindest das erste wollen, aber im Allgemeinen könnten Dateinamen auch Zeilenumbrüche enthalten, was in diesem Fall head
auch nicht viel bringt.
Ich bin verpflichtet, Sie zu warnen, dassDas Parsen der Ausgabe ls
wird als falsch angesehen, anscheinend verstümmeln zumindest einige Versionen die Ausgabe auch ohne Zeilenumbrüche. (Sie sind jedoch möglicherweise auf der sicheren Seite, wenn Sie keine Zeilenumbrüche oder nicht druckbare Zeichen haben. Vielleicht.)
Antwort2
Ich würde einen anderen Ansatz wählen. So etwas wie:
size=20000 # set a limit (in bytes), above these we will delete
for file in *
do
[[ -f "$file" ]] || continue
fileSize=$(stat --format "%s" "$file")
if (( $fileSize > $size )) # if file is bigger than 20000 bytes
then
rm "$file" # delete the file
fi
done
Auf diese Weise können Sie Dateien löschen, die Leerzeichen enthalten, und mit der $size
Variable entscheiden, welche Dateien tatsächlich "groß" sind. Wenn Sie vor jedem Löschen gefragt werden möchten, verwenden Sie den -i
Schalter:rm -i
Bearbeiten:
Mir ist gerade aufgefallen, dass Sie dies unter OS X ausführen. Ich habe im Moment keinen Zugriff auf einen Rechner mit OS X. Es besteht das Risiko, dass OS X stat
ein anderes Format zum Ermitteln der Größe hat. Mit anderen Worten, die --format "%s"
Option funktioniert möglicherweise nicht. Überprüfen Sie man stat
OS X!
Antwort3
ich würde gehen mit;
find . -type f -size +10M -delete -print
Wenn Sie wirklich den ls-Weg gehen möchten, vielleicht;
ls -S | head -1 | while read af; do rm "$af"; done
Antwort4
Verwendenzsh. Es verfügt über eine Methode zum Sortieren und Auswählen von Dateien nach Größe (und nach Datum, das häufiger verwendet wird). Zsh ist Teil der Standardinstallation unter OSX/macOS, muss aber unter Umständen auf anderen Unix-Varianten separat installiert werden.
Die Möglichkeit, Dateien anhand anderer Kriterien als dem Namen auszuwählen (und zu sortieren), istGlob-QualifikationUm beispielsweise die 10 größten Dateien in einem Verzeichnis aufzulisten, OL
sortieren Sie nach absteigender Größe (mLänge) und [1,10]
um die ersten 10 aufzulisten:
ls -ldU *(OL[1,10])
Dies ohne zsh zu tun, ist komplizierter, insbesondere wenn Sie mit Dateinamen umgehen müssen, die Sonderzeichen enthalten. Solange Ihre Dateinamen keine nicht druckbaren Zeichen oder Zeilenumbrüche enthalten, können Sie die Ausgabe von analysieren ls
.
ls -S | head -n 10 | while read -r filename; do echo rm -- "$filename"; done