Pattern Matching Operators

posted May 2, 2012, 7:05 PM by Sachchida Ojha   [ updated May 22, 2013, 9:08 AM ]


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.


Comments