I'm running OS X 10.8.5 so the rename
command is not an option and what I've coded fits in with what the rest of the bash script is doing so I'd prefer to stay within this framework but modify it a bit, if possible. I am however using a later version of bash then the OS X 10.8.5 shipping default, I'm using GNU bash 4.3.30 that I installed from source code. (Yes I know I'm a few patches behind.)
What I'd like to do in the function below, if possible, is to replace the mv
's command target argument which is using command substitution with something totaly in pure bash. More specifically I'd like to eliminate the use of pipes and external executables.
Question: Can the command substitution I'm using either be modified or replaced with filename expansion and or pattern matching not using pipes or external executables to achieve my stated goal? (Or something else more reasonable.)
I've read the three related sections in the Bash Reference Manual however I have to admit I didn't readily see how it might be possible. Although I did try recoding it a few times however the output was not at all what I wanted, it was either mangled filenames or the error ... bad substitution
.
All target filenames in the working directory will either already match RegEx.$ext
or will be RegEx+foobar.$ext
and the way I've coded the function and using mv
is if it's not already matching the RegEx
it renames the target filenames from RegEx+foobar.$ext
to RegEx.$ext
. All filenames when truncated will be unique, so there is no need to worry about overwriting an existing RegEx.$ext
filename and hence no additional error checking needed.
Example Filenames: filenameC01P01.png filenameC01P02foobar.jpg filenameC01P03.tif
Expected Output: filenameC01P02foobar.jpg
-> filenameC01P02.jpg
Code:
function truncate_filenames () {
for f in *.png *.jpg *.tif; do
if [[ -f $f ]]; then
ext="${f:(-3)}"
if [[ ! ${f%.*} =~ .*C[0-9]{2}P[0-9]{2}$ ]]; then
mv -v "$f" "$(echo "$f" | grep -Eo '.*C[0-9]{2}P[0-9]{2}').$ext"
fi
fi
done
}
It appears you just want to strip anything following the CxxPxx
template, but preserve the extension.
# Capture both the good part and the trailing garbage
[[ ${f%.*} =~ (.*C[0-9]{2}P[0-9]{2})(.*)$ ]]
if [[ -n ${BASH_REMATCH[2]} ]]; then
mv -v "$f" "${BASH_REMATCH[1]}.$ext"
fi
You can probably capture the extension in the regular expression as well, eliminating the need to extract it separately.
[[ $f =~ (.*C[0-9]{2}P[0-9]{2})(.*)\.(.*)$ ]]
if [[ -n ${BASH_REMATCH[2]} ]]; then
mv -v "$f" "${BASH_REMATCH[1]}.${BASH_REMATCH[3]}"
fi