Jan 11 2007

Unix shell variable tricks

Published by Brian at 2:09 pm under Computers

One of the nice things about being an administrator of any *nix type operating system is that you tend to learn new things all the time, if not every day.

Recently, I needed to parse the first character off an environment variable, in other words, so that “bdowney” would return “b”.

The script I was writing this for was going to be executed very often, and I wanted to make it as efficient as possible, otherwise I would have used something like this

bdowney$ echo $VAR | /usr/bin/cut -c 1
b

I know perl very well, and in my favorite practical extraction language, I could use something like this:

bdowney$ cat perl.pl
#!/usr/bin/perl $VAR=brian;
$VAR =~ m/(^.)/;
print "$1\n";

bdowney$ ./perl.pl
b

But no external processes, please.

So, digging around through the man page for bash, I discover the deeper side of parameter substitution, which can most simply be described as a regular expression within a variable. It doesn’t allow the flexibility like true regular expressions do, but it offers just enough functionality to make it compelling. So, in my case this will do the trick:

bdowney$ VAR=bdowney; echo ${VAR:0:1}
b

Ah ha! A one-liner that will take care of my need without the reliance of spawing a new process. But much to my chagrin, this will ultimately end up running on a HP-UX system, which doesn’t have BASH by default! The best I can do there is Korn Shell (KSH)… but HP’s implementation doesn’t have the necessary ${VAR:x:x} operator!

Undeterred, I figured out a work-around that will do the same thing on KSH. It’s not as pretty, but still doesn’t call an external process:

bdowney$ VAR=bdowney; SUB=${VAR#?}
> echo ${VAR%%$SUB}
b

Now, try that from your Windows Command Prompt.

One Response to “Unix shell variable tricks”

  1. Johnon 07 Feb 2007 at 7:44 am

    Another interesting “hack” using variable tricks with ksh;

    I wanted to get a filename less the extension … eg. with “myfile.txt” I wanted it to return “myfile” .. again without the massive spawning to count backwards for a “.” ….

    fullfile=myfile.txt
    name_noext=${fullfile%%.*}

    Fantastic ;-) But why is the documentation of these features so difficult to find ?

Trackback URI | Comments RSS

Leave a Reply