Bash loop unzip passworded file script

If you don't have and cannot install zipinfo for any reason, you can imitate it by using unzip with -Z option. To list the contents of the zip use unzip -Z1:

pw="$(unzip -Z1 file1.zip | cut -f1 -d'.')" 
unzip -P "$pw" file1.zip

Put it to a loop:

zipfile="file1.zip"
while unzip -Z1 "$zipfile" | head -n1 | grep "\.zip$"; do
    next_zipfile="$(unzip -Z1 "$zipfile" | head -n1)"
    unzip -P "${next_zipfile%.*}" "$zipfile"
    zipfile="$next_zipfile"
done

or a recursive function:

unzip_all() {
    zipfile="$1"
    next_zipfile="$(unzip -Z1 "$zipfile" | head -n1)"
    if echo "$next_zipfile" | grep "\.zip$"; then
        unzip -P "${next_zipfile%%.*}" "$zipfile"
        unzip_all "$next_zipfile"
    fi
}
unzip_all "file1.zip"

-Z zipinfo(1) mode. If the first option on the command line is -Z, the remaining options are taken to be zipinfo(1) options. See the appropriate manual page for a description of these options.

-1 : list filenames only, one per line. This option excludes all others; headers, trailers and zipfile comments are never printed. It is intended for use in Unix shell scripts.


Ask zipinfo for the filename listed in the zip file, then capture it for the password. Use that password to unzip the file:

pw=$(zipinfo -1 file1.zip | cut -d. -f1)
unzip -P "$pw" file1.zip

Note that the flag to zipinfo is a one not an ell.

Borrowing liberally from Gilles' answer to a similar question, here's a bash loop that will extract a password-protected nested zip file until there are no more zip files:

shopt -s nullglob
while set -- *.zip; [ $# -eq 1 ]
do 
  unzippw "$1" && rm -- "$1"
done

Where I've defined the function unzippw as a wrapper for the zipinfo and unzip commands above:

unzippw ()
{
    local pw=$(zipinfo -1 "$1" | cut -d. -f1)
    unzip -P "$pw" "$1"
}