Multiple RAR extractor / tester in Perl

Hello everyone! :slight_smile:

From time to time I download rar archives from the web. If there’s only a couple of files, you can do this by hand, but when it are a couple of 100 files, then it becomes a pretty hassle.

Now my other scripts are complete, and ready to use, I’ve wrote this script:


#!/usr/bin/perl

use strict;
use warnings;

use Term::ANSIColor qw(:constants);
use Getopt::Long;

sub MyExec {
  my ($exe) = shift; my ($dbg) = shift; my $out = '';
  if($dbg eq 1 ) { $out .= qq(Execute : $exe 
); }
  $out .= qx($exe);
  return $out;
  }

my $w      = '';
my $pref   = '';
my $pw     = '';
my $pass   = '';
my $nopass = 0;
my $tst    = 0;
my $h      = 0;
my $hlp    = 0;
my $debug  = 0;
my $result = GetOptions ("pass|p=s" => \$w, "nopass|n" => \$nopass, "prefix|x=s" => \$pref, "help|h" => \$h, "debug|d" => \$debug, "test|t" => \$tst);

if ($h eq 1) {
  print BOLD,"Usage: ",RESET;
  print("urar -p password -p prefix -t 
-p password of the extracted file(s).
");
  exit;
  };

if(($w eq '') && ($nopass eq 0)) {
  print "No Password given. Please type password, (or just 'enter' for no pw) : ";
  $pw = <STDIN>;
  chomp($pw);
  }
else { $pw = $w; }

if($pw ne '') { $pass = " -p".$pw; }

use File::Path;
my (@dir_contents);
my ($dir_to_open) = "./";

opendir(DIR,$dir_to_open) || die("Cannot open directory !
");
if($pref eq '')       { @dir_contents = grep(/\.rar$/, readdir( DIR )); }
if($pref eq 'part1')  { @dir_contents = grep(/\.part1.rar$/, readdir( DIR )); }
if($pref eq 'part01') { @dir_contents = grep(/\.part01.rar$/, readdir( DIR )); }
closedir(DIR);


my $er_cnt  = 0;
my $ok_cnt  = 0;
my $fl_cnt  = 0;
my @errfile = '';


  
if($tst eq 1) { print BOLD,"
Testing File    : 

",RESET; }
else { print BOLD,"
Extracting File : 

",RESET; }

foreach my $file (@dir_contents)
  {

  print(" - ".$file."
");
  
  my $nwfile = '';
  ($nwfile = $file) =~ s/\.rar$//;

  eval { mkpath($nwfile) };
  
  $file =~ s/(& ()\\]\'\"])/\\$1/g;
  $nwfile =~ s/(& ()\\]\'\"])/\\$1/g;

  my $output = '';
  if($tst eq 1) { $output = MyExec("unrar t ".$pass." ".$file, $debug); }
  else { $output = MyExec("unrar x ".$pass." ".$file." ".$nwfile, $debug); }
  
  my $c  = 1;
  my $ok = 0;
  foreach my $line (split /
]+/, $output) {
    if($debug eq 1) { print qq(line $c : $line
); $c++; }
    if($line eq 'All OK') { $ok = 1; }
    }
  if($ok eq 1) { $ok_cnt++; }
  else { $er_cnt++; push(@errfile, $file); }
  $fl_cnt++;
  }

if($tst eq 1) { print BOLD,"
Files Tested         : ",RESET; }
else { print BOLD,"
Files Extracted      : ",RESET; }
print qq($fl_cnt
);

print BOLD,"
Files with CRC error : ",RESET; print qq($er_cnt
);

if($er_cnt > 0) {
  print BOLD,"
Following files had an error : ",RESET;
  foreach my $fil (@errfile) { print qq($fil
); }
  }


How to use this:

Copy the code, and safe this in a file named: urar
Copy as root this file to: /usr/local/bin
Give it executable rights: chmod +x /usr/local/bin/urar

How to invoke:

Put all your rar files in one directory. If it is a multiple rar archive, with *.part1.rar for example, make shure that these archives are in separate directories. It’s not a problem to put more rar archives with *.part1.rar in one directory.

Now cd on your konsole to the directory where you have stored the files.

To extract type: urar

options are:

if the archives have all the same pw, you can use the -p option: -p pw_here
If you have forgotten to type a pw, you’ll be asked to type one. To circumvent this, use option: -n
For testing the archives, use option: -t
if you want extract archives with part1.rar in its name, use the option: -x part1
For files with part01.rar, use: -x part01
If you like to know what is happening use the option: -d

Hope you enjoy this script. :slight_smile:

Best regards,

Marjon