Come fare in modo ricorsivo decomprimere gli archivi in una directory e le sue sottodirectory da linea di comando Unix?

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

  •  01-07-2019
  •  | 
  •  

Domanda

Il unzip il comando non dispone di un'opzione per ricorsivamente decomprimere archivi.

Se ho la seguente struttura di directory e gli archivi:

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

E voglio decomprimere tutti gli archivi in una directory con lo stesso nome, come ogni archivio:

/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

Quale comando o i comandi dovrei problema?

È importante che questo non soffocare su di nomi di file che contengono spazi.

È stato utile?

Soluzione

Se si desidera estrarre i file nella cartella che si può provare questo

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

Un multi-versione elaborata per i sistemi in grado di gestire velocità di I/O:

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

Altri suggerimenti

Ecco una soluzione che prevede il comando trova e un ciclo while:

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

Una soluzione che gestisce correttamente tutti i nomi di file (compresi i ritorni a capo) e gli estratti in una cartella che si trova nella stessa posizione del file con l'estensione rimosso:

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

Nota che si può facilmente rendere gestire più tipi di file (ad esempio .jar) con l'aggiunta di loro utilizzando -o, ad es.:

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

Si potrebbe utilizzare trovare insieme con l'-exec bandiera in una singola riga di comando per fare il lavoro

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

Qualcosa di simile gunzip utilizzando l'opzione-r bandiera?....

Di viaggio, la struttura di directory in modo ricorsivo.Se uno qualsiasi dei nomi di file specificato sulla riga di comando sono directory, gzip scenderà in directory e comprimere tutti i file che trova (o si decomprimono in caso di gunzip ).

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

Questo funziona perfettamente come vogliamo:

Decomprimere i file:

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

Comando di cui sopra non creare duplicati di directory.

Rimuovere tutti i file zip:

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

Se stai usando cygwin, la sintassi è leggermente diversa per il basename comando.

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

Mi rendo conto che non è molto vecchio, ma è stato tra i primi su Google, quando ero alla ricerca di una soluzione a qualcosa di simile, quindi vi posto quello che ho fatto qui.La mia situazione è leggermente diversa in quanto in pratica ho solo voluto completamente esplodere un vaso, insieme con tutti i barattoli in esso contenute, così ho scritto le seguenti funzioni bash:

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"
}

Nota il <file-where-this-function-is-stored> che è necessario se si memorizza questo in un file che non viene letto per una shell non interattiva, come mi è capitato di essere.Se si memorizza le funzioni in un file caricato non le shell interattive (ad esempio, .bashrc Io credo) è possibile eliminare l'intero source istruzione.Spero che questo possa aiutare qualcuno.

Un po ' di attenzione - explodeFile elimina anche il ziped file, ovviamente si può cambiare, che commentando l'ultima riga.

Un'altra soluzione interessante sarebbe:

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;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top