PATTERN-MATCHING OPERATORS
Operator Function
${var#pattern} Deletes the shortest match of pattern from the front of var and returns the rest.
${var##pattern} Deletes the longest match of pattern from the front of var and returns the rest.
${var%pattern} Deletes the shortest match of pattern from the end of var and returns the rest.
${var%%pattern} Deletes the longest match of pattern from the end of var and returns the rest.
${var/pattern/string} Replaces the longest match of pattern in var with string. Replaces only the first match. This operator is only available in bash 2.0 or greater.
${var//pattern/string} Replaces the longest match of pattern in var with string. Replaces all matches. This operator is only available in bash 2.0 or greater.
The canonical usage of bash’s pattern-matching operators is manipulating
file and path names. For example, suppose you have a shell variable
named myfile that has the value /usr/src/linux/Documentation/ide.txt
(which is the documentation for the kernel’s IDE disk driver). Using
“/*” and “*/” as the pattern, you can emulate the behaviour of the
dirname and basename commands.
1 #!/bin/bash
2 # Listing 34.3
3 # pattern.sh - Demonstrate pattern matching operators
4 #####################################################
5
6 myfile=/usr/src/linux/Documentation/ide.txt
7
8 echo ‘${myfile##*/}=’ ${myfile##*/}
9 echo ‘basename $myfile =’ $(basename $myfile)
10
11 echo ‘${myfile%/*}=’ ${myfile%/*}
12 echo ‘dirname $myfile =’ $(dirname $myfile)
Line 8 deletes the longest string matching “*/” in the filename,
starting from the beginning of the variable, which deletes everything
through the final “/”, returning just the filename. Line 11 matches
anything after “/”, starting from the end of the variable, which strips off just the filename and returns the path to the file. The output of this script is:
$ ./pattern.sh
${myfile##*/} = ide.txt
basename $myfile = ide.txt
${myfile%/*} = /usr/src/linux/Documentation
dirname $myfile = /usr/src/linux/Documentation
To illustrate the pattern-matching and replacement operators, the following command replaces each colon in the $PATH environment variable with a new line, resulting in a very easy to read path display (this example will fail if you do not have bash 2.0 or newer):
$ echo -e ${PATH//:/\\n}
/usr/local/bin
/bin
/usr/bin
/usr/X11R6/bin
/home/kwall/bin
/home/wall/wp/wpbin
Of course, your path statement will look somewhat different. The -e argument to echo tells it to interpret the \n as a new line rather than a literal string. Perversely, however,
you have to escape the escape (\\n) to get the new lines into the variable in order for echo to interpret them.