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.
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