很多shell脚本都涉及修改文件名的操作。我们可能需要在保留扩展名的同时修改文件名、转换文件格式(保留文件名的同时修改扩展名)或提取部分文件名。

shell所具有的一些内建功能允许我们进行文件名相关的处理。

2.12.1 实战演练

借助%操作符可以从name.extension这种格式中提取name部分(文件名)。下面的例子从sample.jpg中提取了sample

  1. $ file_jpg="sample.jpg"
  2. $ name=${file_jpg%.*}
  3. $ echo File name is: $name

输出结果:

  1. File name is: sample
  1. [root@dev workspace]# file_jpg="sample.jpg"
  2. [root@dev workspace]# name=${file_jpg%.*}
  3. [root@dev workspace]# echo File name is: $name
  4. File name is: sample
  5. [root@dev workspace]#

#操作符可以提取出扩展名。

提取文件名中的 .jpg并存储到变量file_jpg中:

  1. $ extension=${file_jpg#*.}
  2. $ echo Extension is: jpg
  3. 输出结果:
  4. Extension is: jpg

2.12.2 工作原理

在第一个例子中,我们使用了%操作符从形如name.extension的格式中提取出了文件名。

${VAR%.*}的含义如下:

  • $VAR中删除位于%右侧的通配符(在上例中是.*)所匹配的字符串。通配符从右向左进行匹配。
  • VAR赋值,即VAR=sample.jpg。通配符从右向左匹配到的内容是.jpg,因此从$VAR中删除匹配结果,得到输出sample

%属于非贪婪(non-greedy)操作。它从右向左找出匹配通配符的最短结果。还有另一个操作符%%,它与%相似,但行为模式却是贪婪的,这意味着它会匹配符合通配符的最长结果。例如,我们现在有这样一个文件:

  1. VAR=hack.fun.book.txt

使用%操作符从右向左执行非贪婪匹配,得到匹配结果.txt

  1. $ echo ${VAR%.*}

命令输出:hack.fun.book

使用%%操作符从右向左执行贪婪匹配,得到匹配结果.fun.book.txt

  1. $ echo ${VAR%%.*}

命令输出:hack

#操作符可以从文件名中提取扩展名。这个操作符与%类似,不过求值方向是从左向右。

${VAR#*.}的含义如下:

  • $VARIABLE中删除位于#右侧的通配符(即在上例中使用的*.)从左向右所匹配到的字符串。

%%类似,#也有一个对应的贪婪操作符##

##从左向右进行贪婪匹配,并从指定变量中删除匹配结果。来看一个例子:

  1. VAR=hack.fun.book.txt

使用#操作符从左向右执行非贪婪匹配,得到匹配结果hack

  1. $ echo ${VAR#*.}

命令输出:fun.book.txt

使用##操作符从左向右执行贪婪匹配,得到匹配结果hack.fun.book

  1. $ echo ${VAR##*.}

命令输出:txt

考虑到文件名中可能包含多个.字符,所以相较于###更适合于从中提取扩展名。##执行的是贪婪匹配,因而总是能够准确地提取出扩展名。

这里有个能够提取域名中不同部分的实例。假定URLwww.google.com

  1. $ echo ${URL%.*} #移除.*所匹配的最右边的内容
  2. www.google
  3. $ echo ${URL%%.*} #将从右边开始一直匹配到最左边的.*(贪婪操作符)移除
  4. www
  5. $ echo ${URL#*.} #移除*.所匹配的最左边的内容
  6. google.com
  7. $ echo ${URL##*.} #将从左边开始一直匹配到最右边的*.(贪婪操作符)移除
  1. [root@dev workspace]# URL='www.google.com'
  2. [root@dev workspace]# echo ${URL%.*}
  3. www.google
  4. [root@dev workspace]# echo ${URL%%.*}
  5. www
  6. [root@dev workspace]# echo ${URL#*.}
  7. google.com
  8. [root@dev workspace]# echo ${URL##*.}
  9. com
  10. [root@dev workspace]#