Problem :
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:
-
To exclude any file from
.part2.rar
(example:*.part{2..99}.rar
) -
With the switch “-x”
I appreciate help completing the loop and integrating decompression of multipart files in .rar
format
Solution :
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 dotpart
,rar
,1
– these matchpart
,rar
and1
literally, respectively[[:digit:]]+
– matches one or more digits (as defined by the current locale)0*
– matches zero or more0
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