
Ich habe eine Gruppe von Ordnern, die alle ZIP-Dateien enthalten, die jeweils 1 oder 2 Dateien in einem neuen Ordner enthalten können. (siehe Diagramm unten)
Ich möchte, dass das Skript auf das oberste Verzeichnis verweist und alle Unterverzeichnisse durchsucht, den Inhalt der ZIP-Datei extrahiert und den Inhalt dieses Unterverzeichnisses eine Ebene nach oben verschiebt (das Löschen der ursprünglichen ZIP-Datei ist optional).
--before--
Photos
-2018
--jan.zip
[--jan1 ]--\
[---jan1.pdf]---}-contents of Zipped file
[---jan1.JPG]--/
--feb.zip
[--feb1 ]--\
[---feb1.pdf]---}-contents of Zipped file
[---feb1.JPG]--/
...
--after--
Photos
-2018
--jan1.pdf
--jan1.JPG
--feb1.pdf
--feb1.JPG
Antwort1
Bevor Sie irgendetwas von dem Folgenden ausführen, erstellen Sie sicherheitshalber eine (rekursive) Kopie Ihres obersten Verzeichnisses.
Dann können Sie das gewünschte Ergebnis wie folgt erzielen:
Machen Sie das oberste Verzeichnis (Fotos) zu Ihrem aktuellen Arbeitsverzeichnis. Extrahieren Sie dann alle ZIP-Dateien:
find . -iname "*.zip" -execdir unzip {} \;
Verschieben Sie nun den Inhalt der extrahierten Verzeichnisse eine Ebene nach oben:
find . -type f ! -iname "*.zip" -execdir mv "$(basename {})" .. \;
Dies hat keine Auswirkungen auf die Zip-Dateien und auch nicht auf die entpackten Verzeichnisse selbst, die in diesem Schritt geleert werden. Sie können sie also jetzt löschen:
find . -mindepth 2 -maxdepth 2 -type d -delete
Bevor Sie die Zip-Dateien löschen, überprüfen Sie noch einmal, ob alles in Ordnung ist. Anschließend können Sie die Löschung durchführen mit
find . -iname "*.zip" -delete
Grundsätzlich können Sie diese Befehle zu einem Skript kombinieren, ich empfehle jedoch, sie zunächst einzeln zu testen und das Ergebnis nach jedem Schritt zu prüfen.
Ein Skript, das Ihr oberstes Verzeichnis als einziges Argument verwendet, kann folgendermaßen aussehen:
#!/bin/bash
cd "$1"
find . -iname "*.zip" -execdir unzip {} \;
find . -type f ! -iname "*.zip" -execdir mv "$(basename {})" .. \;
find . -mindepth 2 -maxdepth 2 -type d -delete
find . -iname "*.zip" -delete
Wenn Sie ihm den Namen „extract“ geben (und die Ausführungsberechtigung festlegen), kann es in seinem eigenen Verzeichnis wie folgt verwendet werden (vorausgesetzt, es handelt ~/photos
sich um Ihr Verzeichnis der obersten Ebene):
./extract ~/photos
Aber Achtung: Dieses Skript wurde nie getestet. Es führt auch keine eigenen Tests durch. Es hängt genau von der Verzeichnis- und Zip-Dateistruktur ab, die Sie beschreiben. Machen Sie also bitte Kopien und Testläufe.