Converting RAR to ZIP in Linux


As ever, mostly notes to myself.

RAR is a silly and proprietary format. I prefer free software and I find that ZIP files are smaller and decompress faster. Not everyone agrees, and that's fine.
Assuming you've downloaded a RAR file and want to convert it to ZIP, what's the easiest way?

Install P7Zip

sudo apt-get install p7zip-full p7zip-rar

Script

This basic bash script will

  1. Extract a RAR example.rar file to a temporary directory on a RAM disk.
  2. Recompress to example.zip.
  3. Delete the temporary directory.

Easy!

It is based on this conversion from CBR to CBZ.

#!/bin/bash
echo "Converting RARs to ZIPs"

# Separate files using ␜ http://graphemica.com/%E2%90%9C.
IFS="␜"

# Use RAM disk for temporary files.
WORKDIR="/dev/shm/"

# Set name for the temp dir. This directory will be created under WORKDIR
TEMPDIR="rar2zip"

# Run using "./rar2zip.sh /full/path/to/files/"
# If no directory is specified, then use the current working directory (".").

if test -z $1; then
   SOURCEDIR=`pwd`
else
   SOURCEDIR="$1"
fi

echo "Using $SOURCEDIR"

# Create an temporary directory to work in.
cd $WORKDIR
mkdir $TEMPDIR
cd $TEMPDIR

# Find all the .rar files in the specified directory.
# Using -iname means it will find .rar .RAR .RaR etc.
# "-printf "%p␜" will cause the file names to be separated by the ␜ symbol,
# rather than the default newline.

for OLDFILE in `find $SOURCEDIR -iname "*.rar" -printf "%p␜"`; do

   # Get the file name without the extension
   BASENAME=`basename "${OLDFILE%.*}"`

   # Path for the file. The ".zip" file will be moved there.
   DIRNAME=`dirname $OLDFILE`

   # Name of the .zip file
   NEWNAME="$BASENAME.zip"

   # Create a temporary folder for unRARed files
   echo "Extracting $OLDFILE"
   mkdir "$BASENAME"
   7z x "$OLDFILE" -O"$BASENAME"
   cd "$BASENAME"

   # Zip the files with maximum compression
   7z a -tzip -mx=9 "$NEWNAME" *
   # Alternative. MUCH SLOWER, but better compression
   # 7z a -mm=Deflate -mfb=258 -mpass=15 -r "$NEWNAME" *

   # Move the new .zip to the directory containing the original ".rar" file
   mv "$NEWNAME" $DIRNAME/"$NEWNAME"

   # Delete the temporary directory
   cd $WORKDIR
   rm -r "$BASENAME"

   # OPTIONAL. Delete the RAR file
   # cd $DIRNAME
   # rm "$OLDFILE"

done

# Delete the temporary directory
cd $WORKDIR
rm -r $TEMPDIR

echo "Conversion Done"

That's it! I suppose it might be nice if there were a simpler way to do it - but this is fairly quick and error-proof.


Share this post on…

5 thoughts on “Converting RAR to ZIP in Linux”

  1. Jay says:

    🙁

    ~/bin/test$ bash -x ../rar2zip.sh *
    + echo 'Converting RARs to ZIPs'
    Converting RARs to ZIPs
    + IFS=␜
    + WORKDIR=/dev/shm/
    + TEMPDIR=rar2zip
    + test -z BabyGroot.rar
    + SOURCEDIR=BabyGroot.rar
    + echo 'Using BabyGroot.rar'
    Using BabyGroot.rar
    + cd /dev/shm/
    + mkdir rar2zip
    + cd rar2zip
    ++ find BabyGroot.rar -iname '*.rar' -printf %p␜
    find: ‘BabyGroot.rar’: No such file or directory
    + cd /dev/shm/
    + rm -r rar2zip
    + echo 'Conversion Done'
    Conversion Done

    Reply
  2. Jay says:

    I found my issue. I was giving a file wildcard not a path. The path also has to be absolute since the script does a "cd" within it. Thanks for sharing

    Reply
  3. FeRD (Frank Dana) says:

    I took this idea and made a few updates, including addressing the issues in the comments here.

    https://gist.github.com/ferdnyc/e3147aa07fd4770ca66a98f19097f7e6

    No longer changes directory
    Takes filenames as arguments, instead of a directory -- can be given multiple files, so if you want to use wildcard(s) just rar2zip.sh /home/me/Downloads/.rar /home/me/Downloads/.RAR
    Quotes all variables to protect paths with spaces in them
    Uses mktemp to create a new temporary directory for each extraction
    Uses rar to extract (my 7z command couldn't read rar files, ymmv)
    Writes the output file in-place, instead of moving it
    Preserves .rar file modification time on .zip
    Refuses to overwrite existing destination files
    Uses gio trash instead of rm, to remove the source file

    Reply

What are your reckons?

All comments are moderated and may not be published immediately. Your email address will not be published.Allowed HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre> <p> <br> <img src="" alt="" title="" srcset="">