I'm writing this off the top of my head, so it's untested code, but it should get you on the right track. It basically walks the tree you point it to, looking for .rar files. Upon finding one, it will uncompress it in place and delete the original archive unless unrar returns nonzero. When hitting a folder, the function will just call itself, causing it to be recursive.
#!/bin/bash
[[ ! -d "$1" ]] && echo "Please point me at a directory!" && exit 1
function recursively_extract_all_rars_in() {
local x=`pwd` f
cd "$1"
for f in (*); do
[[ -d "$f" ]] && recursively_extract_all_rars_in "$f"
[[ -f "$f" ]] && [[ "$f" =~ "*.rar" ]] && unrar e "$f" && rm ${f%%.*}.r??
done
cd "$x"
}
recursively_extract_all_rars_in "$1"
The function name is completely arbitrary. I like to have them read like proper english when invoked with their arguments. [[ -d /path ]]
returns true if the path exists and is a directory. -f
does the corresponding for files. [[ "string" =~ "pattern"]]
is a bashism that allows for pattern matching in strings. It works mostly just like glob patterns.
The line local x=pwd f
might be cryptic, but it just defines two local variables: one called x, to hold the pwd
, and one called f, uninitialized (it's initialized in the for loop below, I just declare it here so it's local).
Storing the pwd
and returning to it if your function uses cd
is a Good Thing (tm).
Please note that using the output of ls
programatically is generally Bad Mojo, and you should avoid it like the pest, in favour of find
. If any of your file names contains a space, using ls in your script will screw up big time. You have been warned.
ZSH
I'm not sure you can do the same thing in Bash, but in ZSH, I'd put the following somewhere in .zshrc
function recursive_unrar() {
for f in **/*.rar; do
local cwd=`pwd` fbn=${f##*/}
cd "${f%/*}"
unrar e "$fbn"
rm "${fbn%%.*}.r{01..99} $fbn"
cd "$cwd"
done
}
And then just call it from inside the corresponding folder.