-->

Bash & Pattern Matching Operators

Pattern-matching operators are most useful for working with freely formatted strings or variable-length records delimited by fixed characters. The $PATH environment variable is an example. Although it can be quite long, the individual directories are colon-delimited. Below list bash’s pattern-matching operators and their function.

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 behavior of the dirname and basename commands.

 

#!/bin/bash
# Listing 34.3
# pattern.sh - Demonstrate pattern matching operators
#####################################################

myfile=/usr/src/linux/Documentation/ide.txt
echo ‘${myfile##*/}=’ ${myfile##*/}
echo ‘basename $myfile =’ $(basename $myfile)

echo ‘${myfile%/*}=’ ${myfile%/*}
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.

Share this Article

Subscribe to our newsletter