Beschleunigen Sie das zufällige Sortieren und Löschen (rm) für mehrere Verzeichnisse

Beschleunigen Sie das zufällige Sortieren und Löschen (rm) für mehrere Verzeichnisse

Ich führe MacOS in einem Terminal aus, das im Wesentlichen BSD ist, und poste meine Frage daher hier statt bei askdifferent. Ich möchte meinen Bilddatensatz in den folgenden Schritten reduzieren, indem ich Dateien nach dem Zufallsprinzip lösche. Einige Verzeichnisse enthalten über 1 Million JPGs. Meine Daten befinden sich im Hauptverzeichnis mit Unterverzeichnissen, die nur eine maximale Tiefe von 1 haben:

-master
     -data1
       image.jpgs
     -data2
       image.jpgs
     -data3
       image.jpgs
     -data4
       image.jpgs
... and so forth

Ich habe diesen Link gefunden:

https://superuser.com/questions/1186350/delete-all-but-1000-random-files-in-a-directory

... und kam zu folgendem Ergebnis:

for f in *.jpg; do find "$f" -type f -print0 | sort -R | tail -n +50001 | xargs -0 rm; done

Obwohl es funktioniert, möchte ich, dass es dies rekursiv für Unterverzeichnisse tut, damit ich es nicht für jedes Verzeichnis manuell tun muss. Meine Fragen/Anfragen sind also:

  1. Kann ich dies irgendwie optimieren, um es zu beschleunigen?
  2. Gibt sort/tail einen Fehler zurück, wenn es auf ein Verzeichnis mit weniger als 50.000 Dateien stößt?

Antwort1

Nachdem ich den verlinkten Quellbeitrag geprüft habe, sieht es so aus, als ob Ihre Schleife eigentlich wie folgt aussehen sollte:

for d in */; do find "$d" -iname '*.jpg' -type f -print0 | sort -zR | tail -zn +50001 | xargs -0r rm; done

Soll aus dem masterVerzeichnis ausgeführt werden.

Die -zOptionen für sortund tailsind notwendig, da die Eingabe durch Nullen getrennt ist. Keiner von beiden beschwert sich, wenn weniger als 50.000 Zeilen vorhanden sind – sortes ist egal und tailes wird nichts ausgegeben, da nach der 50.000. Zeile nichts mehr kommt. rmkönnte sich beschweren, wenn es ohne Argumente ausgeführt wird, aber die -rOption für GNU xargsverhindert die Ausführung, rmwenn es keine Eingabe erhält (BSD xargs benötigt es nicht, wird sich aber wahrscheinlich nicht beschweren).

Zu guter Letzt, aber am wichtigsten, -zwird die Option für nullbegrenzte Eingaben wahrscheinlich nicht von BSD Tail unterstützt. Sie benötigen GNU Tail, das mit Homebrew installiert werden kann.

Sie könnten wahrscheinlich auf durch Nullen getrennte Zeilen verzichten, wenn Ihre Dateinamen garantiert keine Leerzeichen, Zeilenumbrüche, Anführungszeichen, Backslashs usw. enthalten. In diesem Fall:

for d in */; do find "$d" -type f | sort -R | tail -n +50001 | xargs rm; done

verwandte Informationen