A journal to record my notes and ideas related to software development and computing

Friday, October 3, 2008

Replacement in Bash parameter expansions

I have a few utility scripts to make working on the command line easier. One of them is a shortcut for temporarily getting a file or directory out of the way, by renaming it with a .bak suffix. So instead of typing
mv tmp/foo.txt tmp/foo.txt.bak
I can type

bk tmp/foo.txt
and achieve the same thing.

The script to do this was this simple one-liner
mv $1 "$1.bak"

Unfortunately, due to using tab-completion for file names, I'd often get the following error
bk tmp/bar/
mv: rename tmp/bar/ to tmp/bar/.bak: Invalid argument
which is caused by the trailing slash that is included when you tab-complete the directory name. So, ideally, what I wanted to do was check if there was a trailing slash and remove it for the second argument to mv.

Conveniently, this is easily achieved using a feature of Bash parameter expansions:

${parameter/pattern/string}
The pattern is expanded to produce a pattern just as in filename expansion. Parameter is expanded and the longest match of pattern against its value is replaced with string. If pattern begins with ‘/’, all matches of pattern are replaced with string. Normally only the first match is replaced. If pattern begins with ‘#’, it must match at the beginning of the expanded value of parameter. If pattern begins with ‘%’, it must match at the end of the expanded value of parameter. If string is null, matches of pattern are deleted and the / following pattern may be omitted. If parameter is ‘@’ or ‘*’, the substitution operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable subscripted with ‘@’ or ‘*’, the substitution operation is applied to each member of the array in turn, and the expansion is the resultant list.

A quick change to my script and all is well:
mv $1 "${1/%\//}.bak"

Incidentally, calling it with the wrong directory (something like sudo bk /usr/lib) can be a bit disastrous, but that's a different story.

No comments:

About Me

Computer programmer with and interest in music, and a passion for brewing beer, which I'm working at developing into a career!