Sunday, November 30, 2008

Chasing a File's Tail (In BASH)

My very first Unix experience involved the C shell (/bin/csh in your program), and I've always been partial to it, particularly for the ease of using aliases and tabbed file name completion — both available in other shells, of course, but I find this all easier in csh, or its modern descendant, tcsh.

However, when writing shell scripts, I tend to use Bash, mainly because our old AIX machines used the Korn shell (ksh), and Bash is the closest shell to Korn which is readily available on all systems. Besides which, csh programming is frequently considered harmful.

However, one thing that came much more easily to me in csh than in bash (or sh, or dash, or ksh), was the manipulation of file names. Thus, if I have a file named

/home/jhawk/chalmers/pot/dont.smoke

stored in a variable $foibles and just want the file name, not the directory, I write $foibles:t and get dont.smoke as the result. Of course you can do this in Bash as well, but I never remember how to do it. (Actually, I never remember in csh, either, but running foreach on a set of files and trying out $file:a, $file:b, ... , eventually gets me where I want to go.)

So here, as part of the original Linux Notebook function of this blog, is a table for file manipulation in Bash and csh. I've borrowed it from the Bash FAQ, question D3:

Assume

a=/a/b/c/d and b=b.xxx, that is:

$ echo $a $b /a/b/c/d b.xxx

Then

Operation csh bash result
File Path $a:h ${a%/*} /a/b/c
File Name $a:t ${a##*/} d
File Head $b:r ${b%.*} b
File Tail $b:e ${b##*.} xxx