La commande unzip
n'a pas d'option pour décompresser récursivement les archives.
Si j'ai la structure de répertoire et les archives suivantes:
/Mère/Aimer.Zip /Scorbut/Sea Dogs.Zip /Scorbut/Cures/Limes.Zip
Et je veux décompresser toutes les archives dans des répertoires avec le même nom que chaque archive:
/Mère/Aimer/1.txt /Mère/Aimer.Zip /Scorbut/Sea Dogs/2.txt /Scorbut/Sea Dogs.Zip /Scorbut/Cures/Limes/3.txt /Scorbut/Cures/Limes.Zip
Quelle commande ou commandes émettrais-je?
Il est important que cela ne s'étouffe pas sur les noms de fichiers qui contiennent des espaces.
Si vous souhaitez extraire les fichiers dans le dossier correspondant, vous pouvez essayer ceci
find . -name "*.Zip" | while read filename; do unzip -o -d "`dirname "$filename"`" "$filename"; done;
Une version multi-traitement pour les systèmes qui peuvent gérer des E/S élevées:
find . -name "*.Zip" | xargs -P 5 -I fileName sh -c 'unzip -o -d "$(dirname "fileName")/$(basename -s .Zip "fileName")" "fileName"'
Voici une solution qui implique la commande find et une boucle while:
find . -name "*.Zip" | while read filename; do unzip -o -d "`basename -s .Zip "$filename"`" "$filename"; done;
Une solution qui gère correctement tous les noms de fichiers (y compris les sauts de ligne) et extrait dans un répertoire qui se trouve au même emplacement que le fichier, juste avec l'extension supprimée:
find . -name '*.Zip' -exec sh -c 'unzip -o -d "${0%.*}" "$0"' '{}' ';'
Notez que vous pouvez facilement lui faire gérer plus de types de fichiers (tels que .jar
) en les ajoutant à l'aide de -o
, par exemple.:
find . '(' -name '*.Zip' -o -name '*.jar' ')' -exec ...
Vous pouvez utiliser find avec l'indicateur -exec dans une seule ligne de commande pour faire le travail
find . -name "*.Zip" -exec unzip {} \;
Quelque chose comme gunzip utilisant le drapeau -r? ....
Parcourez la structure du répertoire de manière récursive. Si l'un des noms de fichiers spécifiés sur la ligne de commande sont des répertoires, gzip descendra dans le répertoire et compressera tous les fichiers qu'il y trouve (ou les décompressera dans le cas de gunzip).
Cela fonctionne parfaitement comme nous le souhaitons:
Décompressez les fichiers:
find . -name "*.Zip" | xargs -P 5 -I FILENAME sh -c 'unzip -o -d "$(dirname "FILENAME")" "FILENAME"'
La commande ci-dessus ne crée pas de répertoires en double.
Supprimez tous les fichiers Zip:
find . -depth -name '*.Zip' -exec rm {} \;
Une autre solution intéressante serait:
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;
Si vous utilisez cygwin, la syntaxe est légèrement différente pour la commande basename.
find . -name "*.Zip" | while read filename; do unzip -o -d "`basename "$filename" .Zip`" "$filename"; done;
Je me rends compte que c'est très ancien, mais c'était parmi les premiers succès sur Google lorsque je cherchais une solution à quelque chose de similaire, alors je posterai ce que j'ai fait ici. Mon scénario est légèrement différent car je voulais simplement exploser complètement un pot, ainsi que tous les pots qu'il contient, j'ai donc écrit les fonctions bash suivantes:
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"
}
Noter la <file-where-this-function-is-stored>
ce qui est nécessaire si vous stockez cela dans un fichier qui n'est pas lu pour un shell non interactif comme je l'ai été. Si vous stockez les fonctions dans un fichier chargé sur des shells non interactifs (par exemple, .bashrc
Je crois) vous pouvez supprimer la totalité de l'instruction source
. J'espère que cela aidera quelqu'un.
Un petit avertissement - explodeFile
supprime également le fichier compressé, vous pouvez bien sûr changer cela en commentant la dernière ligne.