Saturday, September 09, 2006

parameter substitution in shell

To delete pattern from variable:

Assuming our the value of our variable is 'abracadabra'

my_variable=abracadabra

${variable%pattern} - deletes pattern AFTER variable. That is, if the pattern starts with pattern, it will delete it. If the pattern appears anywhere else than the end, the entire contents of the variable are printed.

echo ${my_variable%ra}

gives:

abracadab


${variable#pattern} - deletes pattern BEFORE variable

echo ${my_variable#abr}

gives:

acadabra

However, if it doesn't begin with 'abr', it will just print the variable (see above)

echo ${my_variable#ra}

gives:

abracadabra


But you can use regular expressions within the match.

Thus:

echo ${my_variable#*ra}

will work from the beginning of the value of the variable and delete everything up until the first occurence of 'ra'. A single '#' tells to substitute the smallest match, but if you use '##', it uses longest possible match (greedy match). Thus

echo ${my_variable##*ra}

will print nothing (or a newline), since the variable ends with 'ra'

Example usage:

To rename a list of files that end in ".bak" to a name without the ".bak":

for xx in `ls *.bak`;do mv $xx ${xx%.bak};done


In the Korn shell, you can also use '?' to match a single character, '[]' to match a set of characters enclosed in the parentheses, e.g., [a-s] will match any letters from a-s, and the negation would be [!a-s] to not match any characters from a-s. A '*' or a '+' will match one or more, e.g., ${my_variable%%+([a-r])} will print a blank. The '()' seem to be needed around the square brackets. I am not sure what the equivalent for this is in bash.

Taken from: UNIX Shell programming, by Kochan & Wood

No comments: