shell 中 贪婪匹配 和 非贪婪匹配

举个栗子:

  

v=jfedu.shiyiwen.com
echo ${v%.*}

 一个%为非贪婪匹配,即匹配最短结果。%从右到左进行非贪婪匹配,匹配什么呢? 匹配已 .*的字符。 那么当然是匹配到了.com 然后执行删除匹配到的字符。结果就是(这里的 "." 相当于定界符。而“*”是通配符)

jfedu.shiyiwen

echo ${v%%.*}

 而这里执行贪婪匹配,即匹配最长结果就匹配到了 .shiyiwen.com 结果为

jfedu

这里在说一个 # 刚好和 %顺序相反而已,#是从左到右来进行匹配的。 老规矩:举个栗子

v=jfedu.shiyiwen.com

echo ${v#*.}
shiyiwen.com

echo ${v##*.}
com

 用处有很多,比较常见的就是很方便的获取文件后缀名和文件名。举个栗子

01.#!/bin/bash  
02.  
03.num=1  
04.for i in *.tar *.tar.gz  
05.do  
06.new=new_$num.${i#*.}      
07.mv $i $new 2>/dev/null  
08.  
09.if [ $? -eq 0 ];then  
10.    echo "remove $i to $new"  
11.    let num++  
12.fi  
13.      
14.done

在补充一些:

${#VALUE}:计算VALUE字符串的字符数量。

  • ${VALUE%.*}${VALUE%%.*}:删除VALUE字符串中以分隔符“.”匹配的右边字符,保留左边字符。
  • ${VALUE#*.}${VALUE##*.}:删除VALUE字符串中以分隔符“.”匹配的左边字符,保留右边字符。
  • ${VALUE/OLD/NEW}${VALUE//OLD/NEW}:用NEW子串替换VALUE字符串中匹配的OLD子串。

    补充:“*”表示通配符,用于匹配字符串将被删除的字串。“.”表示字符串中分隔符,可以为任意一个或多个字符。“%”表示从右向左匹配,“#”表示从左向右匹配,“”表示替换,都属于非贪婪匹配,即匹配符合通配符的最短结果。与“%”、“#”和“/”类似的有“%%”、“##”和“//”,都属于贪婪匹配,即匹配符合通配符的最长结果。

  1. ${VALUE:OFFSET}${VALUE:OFFSET:LENGTH}:从VALUE字符串的左边开始中截取子串。
  2. ${VALUE:0-OFFSET}${VALUE:0-OFFSET:LENGTH}:从VALUE字符串的右边开始中截取子串。

    补充:左边第一个字符从“0”开始,右边第一个字符从“0-1”开始。 表示偏移OFFSET个字符开始,LENGTH表示要截取字符的长度。如果没有LENGTH变量,表示偏移OFFSET个字符开始到字符串结束。

  1. ${VALUE:-WORD}:当变量未定义或者值为空时,返回值为WORD的内容,否则返回变量的值。
  2. ${VALUE:=WORD}:当变量未定义或者值为空时,返回WORD的值的同时并将WORD赋值给VALUE,否则返回变量的值。
  3. ${VALUE:+WORD}:当变量已赋值时,其值才用WORD替换,否则不进行任何替换。
  4. ${VALUE:?MESSAGE}:当变量已赋值时,正常替换。否则将消息MESSAGE送到标准错误输出(若此替换出现在SHELL程序中,那么该程序将终止运行)。

    补充:WORD可以为一个字符串,也可以为一个变量。当为变量时,需要用“$”引用该变量。

另外 ${}的用途,请查看博客的另外一篇博文。

如果对你有帮助,微信扫码关注一下吧!

微信
原文地址:https://www.cnblogs.com/shiyiwen/p/5009666.html