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'
tofind
, and another case tocase
. If there's no option to specify a target directory withunrar
, you could usecd "$(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
Linux - Create Animated Gif with Pan and Zoom
Linking a Static Library into a Shared Library
$${Home} or ${Home} in Makefile
Raising Hard Limit on Rlimit_Nofile System-Wide on Linux
When Is Posix Thread Cancellation Not Immediate
Trouble Ssh Tunneling to Remote Server
Linux Kernel Aio, Open System Call
Using Flycheck/Flymake on Kernel Source Tree
How to Start a Nodejs Process on a Remote Server
When Does a Process Handle a Signal
Find Files and Print Only Their Parent Directories
Cpu Utilization High for Sleeping Processes
Window Placement: Winsplit Revolution -Like Application for Linux (Kde)
Using Dma Memory Transfer in User-Space