3

i run this script but this have a problem with extract rar multiparts

#!/usr/bin/env bash

shopt -s extglob nullglob

passw=(
  passfoo
  passbar
  passfoobar
  banana
  chocolate
  whiskey
  vodka
  icecream
)

for f in *.@(rar|zip|zip.001|7z|7z.001); do
  for p in "${passw[@]}"; do
    if 7z x -y -p"$p" "$f" -aoa; then
      break
    fi
  done
done

With .zip or .7z it decompresses the multiparts well, because the extension of the multiparts are equal (for .7z = 7z.001, 7z.002, etc. For .zip = zip.001, zip.002, etc). The problem is that if I add this to the script:

*.@(rar|part1.rar|zip|zip.001|7z|7z.001)

It fails because *.partX.rar and .rar both end in .rar and the loop unzips the same thing over and over again or fails in .part2.rar onwards if the file has password

Failed attempts to fix the problem:

  1. To exclude any file from .part2.rar (example: *.part{2..99}.rar)

  2. With the switch "-x"

I appreciate help completing the loop and integrating decompression of multipart files in .rar format

1
  • You just want to skip the part[0-9].rar in the loop maybe?
    – Jetchisel
    Commented May 5, 2020 at 9:47

1 Answer 1

1

The first thing to do in the outer loop may be to check if $f qualifies to be skipped.

In Bash you can do this with [[, using either pattern matching (with =, == or !=) or a regex (with =~). The latter option is more powerful. It your case this should work:

for f in *.@(rar|zip|zip.001|7z|7z.001); do
  [[ ( "$f" =~ \.part[[:digit:]]+\.rar$ ) && ! ( "$f" =~ \.part0*1\.rar$ ) ]] && continue
  for p …

The expressions I used consist of these parts:

  • \. – matches a literal dot
  • part, rar, 1 – these match part, rar and 1 literally, respectively
  • [[:digit:]]+ – matches one or more digits (as defined by the current locale)
  • 0* – matches zero or more 0 characters
  • $ – matches the end of string being tested

! negates.

The logic is like this: if the filename ends with .part<digit(s)>.rar and it doesn't end with .part1.rar (or .part01.rar, or .part001.rar etc.) then resume the next iteration (i.e. take the next f and start over).


If I were you, I would add nocaseglob to the shopt -s … line, to match names like FOO.RAR with your pattern (*.@(rar|zip|zip.001|7z|7z.001)). My tests indicate it's enough to make my solution (=~) work with them as well (no need to additionaly enable nocasematch).

shopt -s extglob nullglob nocaseglob
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .