2

I have a huge file that contains zips and rars with zip and rar files located within on a linux box.

I basically need a script or one-liner that will recursively hunt through the directories and unzip and unrar any rar or zip it finds.

migrated from stackoverflow.com Oct 23 '13 at 4:18

This question came from our site for professional and enthusiast programmers.

1

Here is someones solution to this with a shell script.

http://www.dbforums.com/unix-shell-scripts/1619154-how-unzip-files-recursively.html

It would seem that Linux does not have a recursive unzip option :(

  • 1
    It is inappropriate to simply link your source, you should also provide an answer – xenoterracide Oct 10 '13 at 21:53
1

The only way I can think of doing this is to loop multiple times with find and execute a script that removes the files after they've been correctly unpacked. It'll have to go over subdirectories multiple times so it's not exactly efficient. (expected filenames in bold on top)

recursive_unpack

#!/bin/bash
if [ -d "$1" ]; then
   STARTDIR="$1"
else
   echo "starting dir not found: $1"
   exit
fi


COUNTER=1
while [ $COUNTER -gt 0 ]; do
   COUNTER=`find "$STARTDIR" -type f \( -iname '*.zip' -o -iname '*.rar' \) -exec ./unpacker \{\} \; | wc -l`
done

unpacker

#!/bin/bash
BASENAME=`basename "$1"`
BASEDIR=`dirname "$1"`

cd "$BASEDIR"
EXT=`echo "$BASENAME" | awk -F . '{print $NF}'`

if [ "$EXT" = "zip" ]; then
  unzip -qq "$BASENAME"
  if [ $? -eq 0 ]; then
     echo "zip unpacked: $1"
     rm "$BASENAME"
  fi
fi

if [ "$EXT" = "rar" ]; then
  unrar e -y -c- -inul "$BASENAME"
  if [ $? -eq 0 ]; then
     echo "rar unpacked: $1"
     rm "$BASENAME"
  fi
fi

do

chmod u+x recursive_unpack
chmod u+x unpacker

call it with ./recursive_unpack "/my/directory/containing/my/files"

  • recursive_unpack expects unpacker in the same directory
  • unrar and unzip need to be installed
  • if it can't find the directory it'll exit with an error
  • do not remove the echo messages in unpacker, they're used to check for the presence of files to unpack to terminate the loop
1

A quick one-liner, doesn't check if an archive has already been extracted:

$ find . -name '*.rar' -execdir unrar e '{}' + && find . -name '*.zip' -execdir unzip -tq '{}' +
  • I wonder why unrar requires execdir, after reading the man page I think I'll stop using exec. – xenoterracide Oct 10 '13 at 21:52
  • note, edited to add unzip, that's untested – xenoterracide Oct 10 '13 at 21:56
0

Maybe dtrx (http://brettcsmith.org/2007/dtrx/) will do, though I'm not sure whether it handles rar type.

0

Maybe you will find that you have rar part files, and you may want to remove them aswell together with the *.rar, for this you can add this:

find "$BASENAME" -regex '.*\.r[0-9][0-9]' -delete

Here:

  if [ $? -eq 0 ]; then
     echo "rar unpacked: $1"
     rm "$BASENAME"
     # HERE
  fi

And thus the bash will also remove the part files too.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy