Linux Shell Scripting Cookbook(Third Edition)
上QQ阅读APP看书,第一时间看更新

How it works...

To extract the name from the filename formatted as name.extension, we use the % operator.

${VAR%.*} is interpreted as follows:

  • Remove the string match from $VAR for the wildcard pattern that appears to the right of % (.* in the previous example). Evaluating from right to left finds the wildcard match.
  • Store the filename as VAR=sample.jpg. Therefore, the wildcard match for.* from right to left is .jpg. Thus, it is removed from the $VAR string and the output is sample.

% is a nongreedy operation. It finds the minimal match for the wildcard from right to left. The %% operator is similar to %, but it is greedy. This means that it finds the maximal match of the string for the wildcard. Consider this example, where we have this:

VAR=hack.fun.book.txt

Use the % operator for a nongreedy match from right to left and match .txt:

$ echo ${VAR%.*}

The output will be: hack.fun.book.

Use the %% operator for a greedy match, and match .fun.book.txt:

$ echo ${VAR%%.*}

The output will be: hack.

The # operator extracts the extension from the filename. It is similar to %, but it evaluates from left to right.

${VAR#*.} is interpreted as follows:

  • Remove the string match from $VARIABLE for the wildcard pattern match that appears to the right of # (*. in the previous example). Evaluating from the left to right should make the wildcard match.

Similarly, as in the case of %%, the operator ## is a greedy equivalent to #.

It makes greedy matches by evaluating from left to right and removes the match string from the specified variable. Let's use this example:

VAR=hack.fun.book.txt

The # operator performs a nongreedy match from left to right and matches hack:

$ echo ${VAR#*.} 

The output will be: fun.book.txt.

The ## operator performs a greedy match from left to right and matches hack.fun.book:

$ echo ${VAR##*.}

The output will be: txt.

The ## operator is preferred over the # operator to extract the extension from a filename, since the filename may contain multiple . characters. Since ## makes a greedy match, it always extracts extensions only.

Here is a practical example to extract different portions of a domain name such as URL=www.google.com:

    
$ echo ${URL%.*} # Remove rightmost .*
www.google

$ echo ${URL%%.*} # Remove right to leftmost  .* (Greedy operator)
www


$ echo ${URL#*.} # Remove leftmost  part before *.
google.com


$ echo ${URL##*.} # Remove left to rightmost  part before *.
(Greedy operator) com