The goal is to unzip many zip files and rename the resulting file to the original archive name.

Given a folder with many zip files, most of them containing a file called bla.txt, but of course there are some exceptions. All is known is that every file has a single file, which is a txt file.

    a.zip - contains bla.txt
    b.zip - contains bla.txt
    c.zip - contains somethingelse.txt
    d.zip - contains bla.txt
    ...   - ...

output should be


Current best shot, which extracts everything but leaves me with a ton of folders:

for z in *.zip; do unzip $z -d $(echo 'dir_'$z); done

maybe something like

for z in *.zip; do unzip $z; mv 'content_name.txt' $z; done

But how is the content name obtained?


2 Answers 2


You could continue with the -d idea, and simply rename any extracted file to the desired "zip name minus the zip plus txt":

mkdir tmp
for f in *.zip; do unzip "$f" -d tmp && mv tmp/* "${f%.zip}.txt"; done
rmdir tmp

Alternatively, you could pipe the output from unzip into the appropriately-named file:

for f in *.zip; do unzip -p "$f" > "${f%.zip}.txt"; done
  • 1
    The pipe has a (beneficial) side-effect. In case there are more files present (table files in my case) they are appended. This is exactly the behaviour i would want in the exceptional (forbidden even) case of multiple files in a single zip. Jul 31, 2017 at 7:16

The command unzip has its own option unzip -Z1 zipfile.zip to show the actual compressed filename within zipped file which is taking zipinfo's option -1 as it's zipinfo -1 zipfile.zip. so you could simply do as below and there is no need to create a temp directory and mv will done in place in current directory.

for z in *.zip; do 
    unzip "$z";
    mv "$(unzip -Z1 $z)" "${z%%.*}.txt";

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .