Shell 根据扩展名切分文件名,很多shell脚本都涉及修改文件名的操作。我们可能需要在保留扩展名的同时修改文件名、转换文件格式(保留文件名的同时修改扩展名)或提取部分文件名。
shell所具有的一些内建功能允许我们进行文件名相关的处理。

实战演练
借助%操作符可以从name.extension这种格式中提取name部分(文件名)。下面的例子从sample.jpg中提取了sample:
file_jpg="sample.jpg"
name={file_jpg%.*}
echo File name is:name
输出结果:
File name is: sample
#操作符可以提取出扩展名。
提取文件名中的 .jpg并存储到变量file_jpg中:
extension=${file_jpg#*.}
echo Extension is: jpg
输出结果:
Extension is: jpg
工作原理
在第一个例子中,我们使用了%操作符从形如name.extension的格式中提取出了文件名。
${VAR%.*} 的含义如下。
- 从 
$VAR中删除位于%右侧的通配符(在上例中是.*)所匹配的字符串。通配符从右向左进行匹配。 - 
给
VAR赋值,即VAR=sample.jpg。通配符从右向左匹配到的内容是.jpg,因此从$VAR中删除匹配结果,得到输出sample。 
%属于非贪婪(non-greedy)操作。它从右向左找出匹配通配符的最短结果。还有另一个操作符%%,它与%相似,但行为模式却是贪婪的,这意味着它会匹配符合通配符的最长结果。例如,我们现在有这样一个文件:
VAR=hack.fun.book.txt
使用%操作符从右向左执行非贪婪匹配,得到匹配结果.txt:
$ echo ${VAR%.*}
命令输出:hack.fun.book。
使用%%操作符从右向左执行贪婪匹配,得到匹配结果.fun.book.txt:
$ echo ${VAR%%.*}
命令输出:hack。
#操作符可以从文件名中提取扩展名。这个操作符与%类似,不过求值方向是从左向右。
${VAR#*.}的含义如下:
从$VARIABLE中删除位于#右侧的通配符(即在上例中使用的*.)从左向右所匹配到的字符串。
和%%类似,#也有一个对应的贪婪操作符##。
##从左向右进行贪婪匹配,并从指定变量中删除匹配结果。来看一个例子:
VAR=hack.fun.book.txt
使用#操作符从左向右执行非贪婪匹配,得到匹配结果hack:
$ echo ${VAR#*.}
命令输出:fun.book.txt。
使用##操作符从左向右执行贪婪匹配,得到匹配结果hack.fun.book:
$ echo ${VAR##*.}
命令输出:txt。
考虑到文件名中可能包含多个
.字符,所以相较于#,##更适合于从中提取扩展名。##执行的是贪婪匹配,因而总是能够准确地提取出扩展名。
这里有个能够提取域名中不同部分的实例。假定URL为www.google.com:
$ echo ${URL%.*}    # 移除.*所匹配的最右边的内容
www.google
$ echo ${URL%%.*}    # 将从右边开始一直匹配到最左边的.*(贪婪操作符)移除
www
$ echo ${URL#*.}    # 移除*.所匹配的最左边的内容
google.com
$ echo ${URL##*.}    # 将从左边开始一直匹配到最右边的*.(贪婪操作符)移除
com
极客教程