How to Recursively Unzip Nested Zip Files

How do I recursively unzip nested ZIP files?

Thanks Cyrus! The master wizard Shawn J. Goff had the perfect script for this:

while [ "`find . -type f -name '*.zip' | wc -l`" -gt 0 ]; do find -type f -name "*.zip" -exec unzip -- '{}' \; -exec rm -- '{}' \;; done

How do you recursively unzip archives in a directory and its subdirectories from the Unix command-line?

If you want to extract the files to the respective folder you can try this

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

A multi-processed version for systems that can handle high I/O:

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

Recursively unzip all subdirectories while retaining file structure

You could try this:

#!/bin/bash

while :; do
mapfile -td '' archives \
< <(find . -type f -name '*.zip' -o -name '*.7z' -print0)

[[ ${#archives[@]} -eq 0 ]] && break

for i in "${archives[@]}"; do
case $i in
*.zip) unzip -d "$(dirname "$i")" -- "$i";;
*.7z) 7z x "-o$(dirname "$i")" -- "$i";;
esac
done

rm -rf "${archives[@]}" || break
done
  • Every archive is listed by find. That list is extracted in the correct location and the archives removed. This repeats, until zero archives are found.

  • You can add an equivalent unrar command (I'm not familiar with it).

  • Add -o -name '*.rar' to find, and another case to case. If there's no option to specify a target directory with unrar, you could use cd "$(dirname "$i")" && unrar "$i".

  • There are some issues with this script. In particular, if extraction fails, the archive is still removed. Otherwise it would cause an infinite loop. You can use unzip ... || exit 1 to exit if extraction fails, and deal with that manually.

  • It's possible to both avoid removal and also an infinite loop, by counting files which aren't removed, but hopefully not necessary.

  • I couldn't test this properly. YMMV.

How to extract zip file recursively?

When extracting the zip file, you would want to write the inner zip files to memory instead of them on disk. To do this, I've used BytesIO.

Check out this code:

import os
import io
import zipfile

def extract(filename):
z = zipfile.ZipFile(filename)
for f in z.namelist():
# get directory name from file
dirname = os.path.splitext(f)[0]
# create new directory
os.mkdir(dirname)
# read inner zip file into bytes buffer
content = io.BytesIO(z.read(f))
zip_file = zipfile.ZipFile(content)
for i in zip_file.namelist():
zip_file.extract(i, dirname)

If you run extract("zipfile.zip") with zipfile.zip as:

zipfile.zip/
dirA.zip/
a
dirB.zip/
b
dirC.zip/
c

Output should be:

dirA/
a
dirB/
b
dirC/
c

how to unzip all .zip files in folders and subfolders?

This could be done in python, but a bash script might be more ideal.

from glob import glob
import zipfile

zfiles = glob('/myfolder/*/*.zip')
for zpath in zfiles:
zip = zipfile.ZipFile(zpath, 'r')
zip.extractall('/'+'/'.join(zpath.split('/')[0:-1])+'/')
zip.close()


Related Topics



Leave a reply



Submit