Zählen und verschieben Sie Dateien nach Muster

376
Paul Poloskov

Ich habe viele epub-Dateien, die ich in Ordnern organisieren möchte. Alle meine Dateien haben das gleiche Muster "Author - Name (Year) .epub". Was ich versuche zu archivieren, besteht darin, Dateien nach Autoren zu zählen und sie in einen nach Autor benannten Ordner zu verschieben, wenn die Anzahl der Bücher mehr als 2 beträgt (zum Beispiel).

Zum Beispiel für folgende Dateien:

Willis, Connie - [Oxford Time Travel #1] - Doomsday Book (1992).epub Willis, Connie - [Oxford Time Travel #2] - To Say Nothing of the Dog (1997).epub Willis, Connie - [Oxford Time Travel #3] - Blackout (2010).epub Willis, Connie - [Oxford Time Travel #4] - All Clear (2010).epub Wilson, Robert Charles - Julian Comstock - A Story of 22nd-Century America (2009).epub Wilson, Robert Charles - [Spin Saga #1] - Spin (2005).epub 

Alle Bücher von Connie Willis müssen in den Ordner "Willis, Connie" verschoben werden, da sie mehr als 2 zählen, während Bücher von Robert Wilson unberührt bleiben.

Ich fühle mich wirklich verloren und weiß nicht, wo ich damit anfangen soll.

0
Sie erhalten zwar Antworten, die dies in einem Schritt tun, aber ich denke, ein Ansatz durch Aufteilen in einfachere Schritte ist ebenfalls möglich: (1) Erkennen von Autoren und Erstellen von Verzeichnissen; (2) Verschieben Sie jede Datei in ein übereinstimmendes Verzeichnis (es kann jedoch sinnvoll sein, die Schritte 1 und 2 zusammenzuführen). (3) Verzeichnisse mit zwei oder weniger Dateien ermitteln und die Dateien zurück in das Hauptverzeichnis verschieben; (4) Leere Verzeichnisse erkennen und entfernen. // Kannst du einen dieser Schritte ausführen? Kamil Maciorowski vor 5 Jahren 1

1 Antwort auf die Frage

0
Kamil Maciorowski

Drei-Stufen-Lösung cdin ein Verzeichnis, in dem sich die Dateien befinden, und dann:

  1. Dadurch wird jede Datei in das entsprechende Unterverzeichnis verschoben:

    find . -maxdepth 1 -type f -iname "* -*.epub" \ -exec bash -c ' mkdir "$" 2>/dev/null; mv -n -- "$1" "$"/ ' bash {} \; 

    "$"ist ein Teil von "$1"bis zum ersten -(Leerzeichen + Minus). Wir erwarten manchmal, dass das Unterverzeichnis bereits existiert; mkdirwird dann scheitern, es ist OK.

  2. Dadurch werden Unterverzeichnisse mit zwei oder weniger Dateien erkannt und der gesamte Inhalt (zurück) in das aktuelle Arbeitsverzeichnis verschoben:

    find . -mindepth 1 -maxdepth 1 -type d \ -exec sh -c ' [ $(find "$1" -maxdepth 1 -type f -printf "\n" | wc -l) -le 2 ] ' sh {} \; \ -exec sh -c ' find "$1" -mindepth 1 -maxdepth 1 -exec mv -n -t ./ -- \{\} + ' sh {} \; 

    Ändern Sie das -le 2Fragment, um die Anzahl anzupassen. Sie fragen sich vielleicht, warum ich findZeilenumbrüche anstelle von Dateinamen drucken soll (Standardverhalten). Das liegt daran, dass wces sich um ein Textwerkzeug handelt. Mögliche Zeilenumbrüche in Dateinamen beeinträchtigen meine Logik. Durch das explizite Drucken genau eines Zeilenvorschubs pro Datei wird dieses Problem behoben.

  3. Dadurch werden leere Verzeichnisse entfernt:

    find . -maxdepth 1 -type d -empty -delete 

    Es sollte auch ohne funktionieren, -emptyda -delete(like rmdir) ein Verzeichnis nur dann löscht, wenn es leer ist. In diesem Fall möchte ich jedoch die erwarteten Fehlermeldungen unterdrücken, die besagen, dass das angegebene Verzeichnis nicht leer ist. Wenn Sie dies mit tun 2>/dev/null, kann ich jedoch auch keine unerwarteten Fehlermeldungen sehen. Daher das -emptysowieso.

Führen Sie diese Schritt für Schritt aus oder erstellen Sie ein Skript. Es wird empfohlen, die Verzeichnisstruktur vorher zu sichern (z. B. cp -lr my_directory my_directory_backup), falls dies der Fall ist. Einige Optionen, die ich verwendet habe, sind Nicht-POSIX. Diese funktionieren möglicherweise nicht für Sie. Wenn Sie bereits über Unterverzeichnisse verfügen, werden diese möglicherweise durch meine Lösung beeinträchtigt. Passen Sie es dann an Ihre Bedürfnisse an.