Wie entpacken Sie rekursiv Archive in einem Verzeichnis und dessen Unterverzeichnissen aus der Unix-Kommandozeile?

StackOverflow https://stackoverflow.com/questions/107995

  •  01-07-2019
  •  | 
  •  

Frage

Der unzip Befehl nicht eine Option für die Archive rekursiv unzipping.

Wenn ich die folgende Verzeichnisstruktur und Archive:

/Mother/Loving.zip
/Scurvy/Sea Dogs.zip
/Scurvy/Cures/Limes.zip

Und ich möchte alle der Archive in Verzeichnisse mit dem gleichen Namen wie jedes Archiv entpacken:

/Mother/Loving/1.txt
/Mother/Loving.zip
/Scurvy/Sea Dogs/2.txt
/Scurvy/Sea Dogs.zip
/Scurvy/Cures/Limes/3.txt
/Scurvy/Cures/Limes.zip

Welcher Befehl oder Befehle würde ich ausgeben?

Es ist wichtig, dass dies nicht auf Dateinamen nicht ersticken, die Leerzeichen in ihnen haben.

War es hilfreich?

Lösung

Wenn Sie die Dateien in den entsprechenden Ordner extrahieren möchten Sie versuchen, diese können

find . -name "*.zip" | while read filename; do unzip -o -d "`dirname "$filename"`" "$filename"; done;

Eine Mehr verarbeitete Version für Systeme, die hohe E / A verarbeiten kann:

find . -name "*.zip" | xargs -P 5 -I fileName sh -c 'unzip -o -d "$(dirname "fileName")/$(basename -s .zip "fileName")" "fileName"'

Andere Tipps

Hier ist eine Lösung, die den Befehl find und eine while-Schleife beinhaltet:

find . -name "*.zip" | while read filename; do unzip -o -d "`basename -s .zip "$filename"`" "$filename"; done;

Eine Lösung, die alle Dateinamen (einschließlich Zeilenumbrüche) korrekt behandelt und extrahiert in ein Verzeichnis, das an der gleichen Stelle wie die Datei ist, nur mit der Erweiterung entfernt:

find . -name '*.zip' -exec sh -c 'unzip -o -d "${0%.*}" "$0"' '{}' ';'

Beachten Sie, dass Sie leicht es mehr Dateitypen (wie .jar) mit ihnen umgehen, indem das Hinzufügen -o verwenden, z.

find . '(' -name '*.zip' -o -name '*.jar' ')' -exec ...

Sie nutzen könnten zusammen mit dem exec-Flag in einer einzigen Befehlszeile finden die Arbeit zu tun

find . -name "*.zip" -exec unzip {} \;

So etwas wie gunzip der -r Flag verwendet? ....

rekursiv die Verzeichnisstruktur Reisen. Wenn eine der Dateinamen in der Befehlszeile angegebenen Verzeichnisse sind, werden gzip in das Verzeichnis absteigen und komprimieren Sie alle Dateien, die dort gefunden (oder sie im Fall von gunzip dekomprimieren).

http://www.computerhope.com/unix/gzip.htm

Das funktioniert perfekt, wie wir wollen:

Dekomprimieren von Dateien:

find . -name "*.zip" | xargs -P 5 -I FILENAME sh -c 'unzip -o -d "$(dirname "FILENAME")" "FILENAME"'

Vor Befehl erstellt keine doppelten Verzeichnisse.

alle ZIP-Dateien entfernen:

find . -depth -name '*.zip' -exec rm {} \;

Wenn Sie Cygwin verwenden, die Syntax ist etwas anders für den Basisnamen Befehl.

find . -name "*.zip" | while read filename; do unzip -o -d "`basename "$filename" .zip`" "$filename"; done;

Ich weiß, das ist sehr alt, aber es war unter den ersten Treffer bei Google, wenn ich nach einer Lösung zu suchen etwas ähnlich, also werde ich schreiben, was ich hier tat. Mein Szenario ist etwas anders als ich im Grunde wollte nur voll ein Glas zu explodieren, zusammen mit allen Gläsern in sie enthalten, also schrieb ich folgende bash Funktionen:

function explode {
    local target="$1"
    echo "Exploding $target."
    if [ -f "$target" ] ; then
        explodeFile "$target"
    elif [ -d "$target" ] ; then
        while [ "$(find "$target" -type f -regextype posix-egrep -iregex ".*\.(zip|jar|ear|war|sar)")" != "" ] ; do
            find "$target" -type f -regextype posix-egrep -iregex ".*\.(zip|jar|ear|war|sar)" -exec bash -c 'source "<file-where-this-function-is-stored>" ; explode "{}"' \;
        done
    else
        echo "Could not find $target."
    fi
}

function explodeFile {
    local target="$1"
    echo "Exploding file $target."
    mv "$target" "$target.tmp"
    unzip -q "$target.tmp" -d "$target"
    rm "$target.tmp"
}

Beachten Sie den <file-where-this-function-is-stored>, die benötigt wird, wenn Sie diese in einer Datei sind zu speichern, die nicht für ein nicht-interaktiv Shell gelesen wird, als ich zufällig sein. Wenn Sie die Funktionen in einer Datei sind die Speicherung geladen auf nicht-interaktiven Shells (zum Beispiel .bashrc glaube ich) können Sie die gesamte source Anweisung löschen. Hoffentlich wird dies jemand helfen.

Eine kleine Warnung - explodeFile löscht auch die geZIPten Datei, können Sie sich natürlich ändern, dass durch Kommentare, die letzte Zeile aus

.

Eine weitere interessante Lösung wäre:

DESTINY=[Give the output that you intend]

# Don't forget to change from .ZIP to .zip.
# In my case the files were in .ZIP.
# The echo were for debug purpose.

find . -name "*.ZIP" | while read filename; do
ADDRESS=$filename
#echo "Address: $ADDRESS"
BASENAME=`basename $filename .ZIP`
#echo "Basename: $BASENAME"
unzip -d "$DESTINY$BASENAME" "$ADDRESS";
done;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top