Tausende von Dateien in Ordnern mit einem bestimmten Namen ablegen

Tausende von Dateien in Ordnern mit einem bestimmten Namen ablegen

ich habe einen Ordner namens „Test“, der nur JPEG-Dateien enthält. Tausende von Dateien. Ich muss diese Tausenden von Dateien, die Namen wie 1.jpg, 2.jpg ... 345623.jpg haben, in Unterordner mit Namen wie 001000, 002000 verschieben, die jeweils 1000 Dateien enthalten. Ich muss also alle JPG-Dateien aus dem Testordner auf die leistungsstärkste und effizienteste Weise in Unterordner verschieben, die jeweils 1000 JPG-Dateien enthalten.

Was ich bisher habe, ist:

i=1;while read l;do mkdir $i;mv $l $((i++));done< <(ls|xargs -n1000)

Antwort1

find . -type f \
| split -l 1000 -a 3 --numeric-suffixes=1 \
  --filter='target="${FILE}000"; mkdir "$target" && xargs -d "\n" mv -t "$target"' \
  - ''

Erläuterung:

  • find . -type ffindet Dateien (auch in Unterverzeichnissen, aber ich glaube, in deinem Fall gibt es noch keine Unterverzeichnisse).
  • split -l 1000 -a 3 --numeric-suffixes=1 ... - ''liest von seinem Standardeingang ( -) und teilt die Daten in Blöcke auf, wobei jeder Block 1000 Zeilen lang ist ( -l 1000). Jedem Block wird ein „Name“ zugeordnet, der aus dem leeren Präfix ( '') und einem numerischen Suffix, beginnend bei 1 ( --numeric-suffixes=1), mit einer Länge von 3 ( -a 3) besteht. Tatsächlich lauten die Namen an dieser Stelle 001, 002und so weiter.
  • --filter=...führt den angegebenen Befehl für jeden Chunk separat aus, der jeweilige Name steht als $FILE. Der auszuführende Befehl lautet

    target="${FILE}000"; mkdir "$target" && xargs -d "\n" mv -t "$target"
    
    • target="${FILE}000"wandelt den Namen beispielsweise 001oder 002in den gewünschten zukünftigen Verzeichnisnamen ( 001000oder 002000usw.) um und speichert diesen in der targetVariablen.
    • mkdir "$target"erstellt ein neues Verzeichnis mit dem gewünschten Namen.
    • xargs -d "\n" ...liest den gesamten Block (1000 Dateipfade oder weniger im letzten Block) und verwendet jede ganze Zeile (neue Zeile als Trennzeichen: -d "\n") als Argument für den folgenden Befehl.
      • mv -t "$target"verschiebt Objekte (übergeben von xargs) in das neu erstellte Verzeichnis.

Anmerkungen:

  • Der Befehl kümmert sich nicht um Dateinamen. 345623.jpgendet nicht unbedingt in 346000/. Mögliche Gründe:
    • findsortiert nicht; aber selbst wenn Sie sort -nzwischen findund setzen split, kann es sein ...
    • es gibt Lücken in der Nummerierung. splitbenötigt in jedem Fall 1000 Einträge (außer es handelt sich um den letzten Block; in diesem Fall 1000 oder weniger).
  • mkdir ... && xargs ...xargswird bei einem Fehler nicht ausgeführt mkdir(Vorsicht bei vorhandenen Verzeichnissen).
  • Verwenden Sie cp -l -t "$target"anstelle von mv -t "$target", um Hardlinks in Verzeichnissen zu erstellen, wobei bereits vorhandene Einträge im aktuellen Verzeichnis intakt bleiben. Auf diese Weise können Sie, falls etwas schief geht, einfach rm -rdie Verzeichnisse verschieben und von vorne beginnen. mvWenn Sie die Aufgabe mit unterbrechen, werden am Ende einige Dateien verschoben, andere nicht; das kann ein Chaos sein.
  • Ich glaube, -a 3Sie kommen damit nicht weiter 999( 999000nach dem Anhängen von Nullen am Ende). Wenn splitweitere Chunks erstellt werden müssen, schlägt dies mitten im Job fehl. Stellen Sie deshalb sicher, dass 999genug vorhanden ist, bevor Sie den Befehl ausführen.
  • Namen mit Zeilenumbrüchen beschädigen den Code (im Allgemeinen sehen Ihre Dateinamen gut aus).

verwandte Informationen