曲径通幽论坛

标题: ${variable#pattern}| ${variable##pattern}| ${variable%pattern}| ${variable%%p [打印本页]

作者: beyes    时间: 2010-7-7 22:44
标题: ${variable#pattern}| ${variable##pattern}| ${variable%pattern}| ${variable%%p
1. ${variable#pattern}
表达式的意思是,如果 pattern 匹配,那么将删除掉最短的那部分匹配,然后将剩下的返回。
测试脚本代码如下:
#!/bin/sh

main_name=/usr/include/sys/stat.h

main_name=${main_name#/*/}

echo $main_name
运行与输出:
sh pattern_match.sh
include/sys/stat.h
脚本中的匹配处理意思是,从 /usr/include/sys/stat.h 这个字符串的开始找起,一旦找到两个斜杠,则将他们之间的任何内容,包括两个斜杠本身,都会被删除。

2. ${variable##pattern}
表达式的意思是,如果匹配 pattern 匹配,那么将删除最长那部分匹配,然后将剩下的返回。
修改上面的脚本中的 main_name=${main_name#/*/} 为 main_name=${main_name##/*/},那么再运行输出时有:
sh pattern_match.sh
stat.h

3. ${variable%pattern}
表达式的意思是,pattern 的匹配是从 variable 的末尾开始匹配,若匹配,则删除掉最短那部分匹配。
测试脚本代码如下:
#!/bin/sh

main_name=/tmp/shell_1/shell_2/long.file.name

main_name=${main_name%.*}

echo $main_name
运行与输出:
sh pattern_match.sh
/tmp/shell_1/shell_2/long.file

4. ${variable%%pattern}
类似于 # 和 ## 的关系,pattern 的匹配时从 variable 的末尾开始匹配,若匹配,则删除掉最长的那部分匹配。修改上面脚本中
的 main_name=${main_name%.*} 为 main_name=${main_name%%.*},这时再运行输出:
sh pattern_match.sh
/tmp/shell_1/shell_2/long

注意,上面的“最短”和“最长”是在有通配符 * 号时才可以看到区别,但在精确匹配中,我们看到输出是一样的,如
main_name=${main_name%.} 和 main_name=${main_name%%.} 的输出是一样的。

关于应用:
像 ${variable##pattern} 这种形式作用和命令 basename 一样,都是去掉文件名的路径信息。但是如果要处理大量的文件时,从效率上考虑,应该使用
${variable##pattern} 这种形式,而不是使用 basename 命令。因为 basename 是在自身进程里处理的而不是在 shell 里进行处理。类似的,dirname 的作用
和 ${variable%/*} 一样,只列出目录前缀。同样的基于效率的考虑,我们会在 shell 里使用 ${variable%/*} 而不是 dirname 命令。

5. ${variable/pattern/string} 和 ${variable//pattern/string}
两种形式的作用都是替换。
第一种形式表示,用 string 替换掉 variable 中第一个匹配 pattern 。
第二种形式表示,用 string 替换掉 variable 中所有匹配的 pattern 。

举例:
echo -e ${PATH//:/'\n'}
/sbin
/usr/sbin
/usr/local/sbin
/root/bin
/usr/local/bin
/usr/bin
/bin
/usr/bin/X11
/usr/X11R6/bin
/usr/games
/usr/lib/mit/bin
/usr/lib/mit/sbin
这里,我们将 PATH 变量中的 : 号用换行来取代,这样每一个默认路径就看得很清楚了。




欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/) Powered by Discuz! X3.2