How-To Geek
Unzip or Unrar Many Files at Once in Linux
If you’ve got a directory with dozens of zipped or rar’d files, you can run a single command to unzip them all in one step, thanks to the power of the bash shell.
For this task, we’ll use bash’s for loop command structure. Replace <var> with a variable name, and <list> with either a command that outputs a list or an explicit list.
for <var> in <list>
do
command $<var>;
done
You can run it on a single line with this syntax instead:
for <var> in <list>;do command $<var>;done
So if you want to unrar a list of files, you could use this command. You don’t necessarily need the quotes, but it helps when the filenames have spaces or something like that in them.
for f in *.rar;do unrar e “$f”;done
If you wanted to use 7zip to extract a list of files:
for f in *.001;do 7z e “$f”;done
Or if you wanted to unzip a list of files:
for f in *.zip;do unzip “$f”;done
You could even chain commands together if you wanted to. For instance, if all your zip files contained .txt files and you wanted to unzip them and then move the unzipped files to another directory:
for f in *.zip;do unzip “$f”;done; for f in *.txt;do mv “$f” /myfolder/;done
The bash shell is just so incredibly powerful… this doesn’t even tap the power, but it should give you a good idea of what is possible.
Got Feedback? Join the discussion at discuss.howtogeek.com
Comments (25)
Programmer by day, geek by night, The Geek, also known as Lowell Heddings, spends all his free time bringing you fresh geekery on a daily basis. You can follow him on Google+ if you'd like.
- Published 05/28/07




Actually, I’m pretty sure with both these commands you can just do this:
unzip *.zip
unzip *.rar
Seems a bit more straightforward. :-)
That may work sometimes, but didn’t work for me. (just tried it again to make sure)
The article is mostly illustrating how to use the for / do in bash =)
How would I go about ‘rarring’ :) or zipping a bunch of folders?
Is there a decompressor that extracts almost all file types, if so which?
find -name *.zip -exec unzip {} \;
Try unzip \*.zip – It works in RED HAT flavours, I have not tried it on any other linux.
Why didn’t i find this 3 days ago? The only matter is that the files aren’t extracted in subdirectories. I made a similar script myself. Take a look: http://ubuntu.alperortac.de/2008/01/30/automatically-extract-all-archives-in-current-directory-to-subfolders/
Maybe Alp wants something like this:
for f in *.zip;do unzip “$f” -d “$f.inflated”;done
It works on my Debian.
PS: I’ve not seen Alp link cause it seems broken.
Sorry for the broken link, and thanks for pointing that out. It’s fixed now.
Very useful tutorial! Thanks!
I modified mine a bit to account for archives which ask for confirmation. If you ‘man unzip’ you’ll find a -o switch which: “-o overwrite files WITHOUT prompting”
So my .sh script amounted to:
for f in *.zip;
do unzip -o -d “$f”;
done
Hope this helps someone! Regards,
Ax3
Looks like my previous code post didn’t go thru completely. I meant on the second line of code:
do unzip -o -d foldername/ “$f”;
Ax3
I know this page is old, but I just found it when looking for a good unrar script, so thought I would post my final solution. The situation: you’re in a directory with a bunch of folders, each one containing a compressed file. I used to use this script, which found and extracted all the *.rar files:
find -type f -name ‘*.rar’ -exec unrar x {} \;
But then i noticed some of my compressed files were distributed over many ‘part’ files, and occasionally, all of these would be *.rar files, and so this script would try to do the whole decompression for part file, which was annoying, time consuming and more importantly not the elegant solution! So after a bit of reading, I came up with this:
for directory in `ls -d */`; do
rarFile=`ls $directory | grep -i .rar –max-count 1`;
unrar e $directory$rarFile;
done
This iterates through each directory at the current level, and for each one finds just the first *.rar file, and extracts it to the current directory.
thx a lot!!! :)
I know this is old … but 1jackjack .. i found the same thing using
find -type f -name ‘*.rar’ -exec unrar x {} \;
i changed it simply to
find -type f -name ‘*.rar’ -exec unrar x -o- {} \;
which stops it extracting if files already exist …
cheers ..
I found a variation of the command above will extract files to each sub-directory rather than the parent directory, see below
find -type f -name ‘*.rar’ -execdir unrar x -o- {} \;
Apologies the script above does not cater for rar files over many parts.
It will extract and overwrite the previous file even with the -o- option.
e.g.
myfile.part01.rar
myfile.part02.rar
myfile.part03.rar
the rar files above will be processed 3 times, each time extracting the same file which will overwite the last
It is probably best to stick with -exec option rather than -execdir, unless someone else can figure out a way around this
If you copy and paste the above make sure you change the ‘quotes’ to the proper unix single quotes because the webpage has converted them into curly front/back quotes
Thanks! Kharn, you had exactly what I needed. Much appreciated from a linux noob.
Is there an easy way to rename the results to the same name as the directory they were extracted in?
Why don’t you simply use
unzip ‘*.zip’
unrar e ‘*.rar’
Just use the apostrophe around the name template using wildcards.
here is a script that I use to unrar and unzip find in a predefined location.
######################################
#!/bin/bash
LOCKFILE=”/tmp/${0}.log”
DOWNLOADDIR=’/mnt/downloads/finished/TV’
FINDCOMMAND=’/opt/bin/find’
echo “Started: “`date +%m/%d/%y\ %H:%M\ %Z`
echo “As:”`whoami`
# ************
# Add a quick check to see if another check is running
if [ -f "$LOCKFILE" ]; then
echo “Already running!”
exit
fi
echo Creating Lock File
touch “$LOCKFILE”
OLD_IFS=”$IFS”
IFS=$’\n’
echo ” ”
echo “Searching for rars in $DOWNLOADDIR”
echo ” ”
ARCHIVES=$( “$FINDCOMMAND” “$DOWNLOADDIR” -type f -regex .*\.[Rr][Aa][Rr] )
for f in $ARCHIVES; do
CURDIR=”${f%/*}”
PARTCHECK=$(expr “$f” : ‘.*\([Pp][Aa][Rr][Tt][0-9]\+\.[Rr][Aa][Rr]\)’)
echo Processing: “$f”
if [ "$PARTCHECK" ]; then
echo Multipart Archive Detected
PART1=$(expr “$f” : ‘.*\([Pp][Aa][Rr][Tt]0\+1\.[Rr][Aa][Rr]\)’)
if [ "$PART1" ]; then
echo Extracting Multipart Archive
nice -n 19 unrar x -o+ “$f” “$DOWNLOADDIR”
if [ "$?" == "0" ]; then
if [ "$DOWNLOADDIR" != "$CURDIR" ]; then
echo Removing “$CURDIR”
nice -n 19 rm -fR “$CURDIR”
echo Extraction Successful
fi
else
echo Extraction Failed
fi
else
echo Skipping Archive Part
fi
else
nice -n 19 unrar x -o+ “$f” “$DOWNLOADDIR”
if [ "$?" == "0" ]; then
if [ "$DOWNLOADDIR" != "$CURDIR" ]; then
echo Removing “$CURDIR”
nice -n 19 rm -fR “$CURDIR”
echo Extraction Successful
fi
else
echo Extraction Failed
fi
fi
echo ” ”
done
echo “Searching for zips in $DOWNLOADDIR”
ARCHIVES=$( “$FINDCOMMAND” “$DOWNLOADDIR” -type f -regex .*\.[Zz][Ii][Pp] )
for f in $ARCHIVES; do
CURDIR=”${f%/*}”
nice -n 19 unzip -o “$f” -d “$DOWNLOADDIR”
if [ "$?" == "0" ]; then
if [ "$DOWNLOADDIR" != "$CURDIR" ]; then
echo Removing “$CURDIR”
nice -n 19 rm -fR “$CURDIR”
echo Extraction Successful
fi
else
echo Extraction Failed
fi
echo ” ”
done
IFS=”$OLD_IFS”
rm “$LOCKFILE”
echo “Finished: “`date +%m/%d/%y\ %H:%M\ %Z`
The above does require your find command to support regular expressions, if your not sure check the man file.
how can extract all files which are in format of abc.zip.bz2 newone.zip.bz2 at single command to remove the bzip2 and unzip that file abc.zip , is this possible in linux
I notice this is an old thread but I still see people replying so I give this a go.
find -type f -name ‘*.rar’ -exec unrar x -o- {} \;
This does almost exactly what I want the script to do. But what should be added to rename the unpacked file to it’s parent directory?
So for example I have ‘This.Doc.Is.Important’ as parent dir and with a filename called ‘Important.txt’ so after unpack it should be renamed as ‘This.Doc.Is.Important.txt’
I have been using these instructions for a while. I have a question about it. If one is uncompressing multiple files which all contain, among others, a file with the same name, one is always asked by bash if eh wants to abort, overwrite or rename this file…how can one do that? How can one use the commands in the main post above, and answer yes, for example, to questions asked by the executing shell?
Thanks