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.

3 thoughts on “Converting RAR to ZIP in Linux

  1. 🙁

    ~/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

  2. 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

Leave a Reply

Your email address will not be published. Required fields are marked *