Löschen Sie alle bis auf 1000 zufälligen Dateien in einem Verzeichnis

13

Ich habe ein Datengenerierungsskript zu lange laufen lassen und habe jetzt mehr als 200.000 Dateien, die ich auf etwa 1000 reduzieren muss. Über die Linux-Befehlszeile gibt es eine einfache Möglichkeit, alle bis auf 1000 dieser Dateien zu löschen, wobei die Dateien beibehalten werden hätte keine Abhängigkeit von Dateinamen oder einem anderen Attribut?

Malcolm Regan
quelle
Hatte der Prozess, der die Dateien erstellt hat, eine Eigenschaft, die jede Datei mit der vorherigen verknüpft? Wenn ja, wäre es wichtig, zufällig auszuwählen, um eine repräsentative Stichprobe zu erhalten. Wenn der Prozess Dateien generiert, die von Natur aus zufällig sind, können Sie einfach alles nach den ersten 1000 löschen.
fixer1234

Antworten:

15

Löschen Sie alle bis auf 1000 zufälligen Dateien in einem Verzeichnis

Code:

find /path/to/dir -type f -print0 | sort -zR | tail -zn +1001 | xargs -0 rm

Erläuterung:

  1. Listen Sie alle Dateien /path/to/dirmit auf find;
    • print0: benutze \0( Nullzeichen ) als Zeilenbegrenzer; Dateipfade mit Leerzeichen / Zeilenumbrüchen unterbrechen das Skript also nicht
  2. Mische die Dateiliste mit sort;
    • -z: Verwenden Sie \0(Nullzeichen) als Trennzeichen anstelle von \n(eine neue Zeile)
    • -R: zufällige Reihenfolge
  3. Entfernen Sie die ersten 1000 Zeilen aus der zufälligen Liste mit tail;
    • -z: Behandle die Liste als nullbegrenzt (wie bei sort)
    • -n +1001: Zeilen ab 1001 anzeigen (dh erste 1000 Zeilen weglassen)
  4. xargs -0 rm - die restlichen Dateien entfernen;
    • -0: wieder nullbegrenzt

Warum ist es besser als die Lösung von Quixotic *:

  1. Funktioniert mit Dateinamen, die Leerzeichen / Zeilenumbrüche enthalten.
  2. Versucht nicht, Verzeichnisse zu erstellen (die übrigens möglicherweise bereits vorhanden sind).
  3. Verschiebt keine Dateien, berührt nicht einmal die 1000 "glücklichen Dateien", außer sie mit aufzulisten find.
  4. Vermeidet das Fehlen einer Datei, falls die Ausgabe von aus irgendeinem Grund findnicht mit \n(newline) endet.

* - Kredit quixotic für | sort -R | head -1000, gab mir einen Ausgangspunkt.

rld.
quelle
Unter CentOS 6 wurden Fehler bei ungültigen Operanden angezeigt. Glücklicherweise geht es mir nicht um Leerzeichen in Dateipfaden, so dass das Entfernen dieser Operanden für mich funktioniert hatfind . -type f | sort -R | tail -n +1001 | xargs rm
Brad
@brad Könnten Sie die Fehlermeldungen und Ihre Version von angeben find ? Ich werde versuchen, meine Antwort zu verbessern, brauche nur etwas Input, um damit zu arbeiten.
rld.
3
tail: invalid option -- 'z'Die Version von Schwanz, die ich habe, ist 8.4
Brad
Ich würde --no-run-if-empty zu xargs hinzufügen, um Fehler zu vermeiden, wenn keine Datei vorhanden ist (nachdem ich sie beispielsweise zweimal ausgeführt habe).
ich
1

Verwenden Sie ein temporäres Verzeichnis, dann findalle Ihre Dateien, sortieren Sie die Liste sortnach dem Zufallsprinzip und verschieben Sie die obersten 1000 der Liste in das temporäre Verzeichnis. Löschen Sie den Rest und verschieben Sie die Dateien aus dem temporären Verzeichnis zurück.

$ mkdir ../tmp-dir
$ find . -type f | sort -R | head -1000 | xargs -I "I" mv I ../tmp-dir/
$ rm ./*
$ mv ../tmp-dir/* .

Wenn Sie xargssich über die Zeilenlänge beschweren, verwenden Sie eine kleinere Zahl mit headund wiederholen Sie den Befehl nach Bedarf (dh wechseln Sie -1000zu -500und führen Sie ihn zweimal aus oder wechseln Sie zu -200und führen Sie ihn fünfmal aus.)

Es kann auch keine Dateinamen verarbeiten, die Leerzeichen enthalten. wie @ Antwort des rld zeigt, können Sie find‚s -print0Argument, die -zArgumente sortund head, und -0mit xargszu richtigen Dateinamen Handhabung zu gewährleisten.

Wenn das tmp-dirbereits vorhanden ist, sollten Sie einen Verzeichnisnamen ersetzen, der nicht vorhanden ist.

quixotic
quelle
Dies schlägt fehl, wenn einer der durch aufgelisteten Dateinamen findein Leerzeichen enthält.
rld.
0

Für Mac-Benutzer sollte das folgende Skript ausreichen.

find . -type f -print0 | tr '\0' '\n' | sort -R | tail -n +10000 | tr '\n' '\0' | xargs -0 rm

trermöglicht es sort und tail, Listen mit \nstatt zu bearbeiten \0.

Luca Di Liello
quelle
-2

Am einfachsten ist es, das Verzeichnis rm -rf zu erstellen und dann das Datengenerierungsskript erneut auszuführen, ohne darauf zu achten, dass es zu lange ausgeführt wird.

Lars Poulsen
quelle
Das hat das OP nicht gefragt. Vielleicht ist das nicht machbar.