You are here

comparing strings in the shell

While creating materials for my bash class I needed to create some globbing exercises for my students.

It occured to me that a string operator and a comparison to the null string can be used to check if something is a substring of another value.

Sure, you can use Substring Expansion to see if the substring is at a known location such as "Does the value of $foo start with 'bar'?", but length and location are often unknown.

Say, for instance, I wanted to know if it's a word a Dalek would shriek? Easy to do with regular expressions: grep ate$ /usr/share/dict/words.

Since I was building a globbing exercise, regexen would be cheating, so that was out.

Using the 'Remove matching prefix pattern' ( I call it truncate ) operator, one can glob and match to an empty string.

DALEK# foo=SENATE
DALEK# if [ '' = "${foo%%*ATE}" ] ; then add_to_dalek_vocabulary "$foo"; fi
SENATE added.
DALEK#

Note the double percent sign. Default string operator globbing is non-greedy, so we need to double down to get greedy matching.

DALEK# foo="PARLIAMENT"
DALEK# if [ '' = "${foo%%*ATE}" ] ; then add_to_dalek_vocabulary "$foo"; fi
DALEK#

This works for anywhere in the string matching as well.

LIGHTNING% foo='bicarbonate'
LIGHTNING% if [ '' = "${foo%%*car*}" ] ; then open_to_pixarization "$foo"; fi
bicarbonate added.
LIGHTNING% foo='dihydrogen oxide'
LIGHTNING% if [ '' = "${foo%%*car*}" ] ; then open_to_pixarization "$foo"; fi
LIGHTNING%

Easy enough to make the search string a variable as well.

DALEK# eight=ATE
DALEK# bar='bicarbonate'
DALEK# foo=${bar^^}
DALEK# echo $foo
BICARBONATE
DALEK# if [ '' = "${foo%%*${eight}}" ] ; then add_to_dalek_vocabulary "$foo"; fi
BICARBONATE added.
DALEK#

The double eyebrow conversion was the 'Case modification' string operator. Don't tell my students, we haven't gotten there yet :).

Anyway, glob for the win.