Matching words against a list in the Bourne Shell
One of the interesting challenges in writing shell scripts is figuring out how to do as much as is practical with shell builtins and primitives. Since Bourne shell builtins are such a limited and constrained environment, the results can be somewhat perverse and peculiar and thus neat and amusing.
(If you can find an efficient way of doing things, using builtins is much faster than having to resort to external programs, especially when the system is loaded.)
My challenge today was checking whether a word was in a list of words (words don't have spaces), in a Bourne shell dialect that would work as far back as Solaris 2.5. What I came up with is:
case "$wlist" in $w|"$w "*|*" $w "*|*" $w") echo yes;; *) echo no;; esac
(Where $w
is the word and $wlist
is the space-separated list of
words to match against. You need the first match condition to deal
with the case where $wlist
consists only of $w
.)
I sometimes feel I have an advantage in this sort of perversity, because
I started out writing shell scripts in a version of the Bourne shell
that was so old that it didn't even have test
(aka [ ... ]
) as a
builtin. When you don't have a built in test
you get a lot of
experience with abusing case
, because it is basically the only builtin
testing operation you have.
(To this day I have a tendency to use case
for condition tests where
I really should use if
. Something in the back of my mind is still not
really convinced that things like 'if [ "$#" -eq 0 ]
' don't require
an external program.)
Comments on this page:
|
|