0%

shell变量扩展

1. 基础知识

1.1 变量引用

shell引用变量的基本格式 ${parameter}

  • 如果parameter是数字,则是参数扩展
  • 如果parameter是字符串,则是变量扩展
  • 如果parameter是数组,遵循数组的扩展规则;
  • parameter还可以是@ * # ? -等特殊参数,参考特殊参数的引用

1.2 变量扩展

1.2.1 模式扩展

1.2.1.1 ${value#pattern}

删除value中与pattern相匹配的部分,从左向右匹配

1
2
3
value=www.skygroup.com
echo ${value#*.}
输出 skygroup.com

1.2.1.2 ${value##pattern}

也是删除value中与pattern相匹配的部分,从左向右匹配,但是#与##的区别在于贪婪模式上

  • #是非贪婪模式,也即最短匹配模式 lazy
  • ##是贪婪模式,也即最长匹配模式 greedy
1
2
3
value=www.skygroup.com
echo ${value##*.}
输出 com

1.2.1.3 ${value%pattern}

删除value中与pattern相匹配的部分,但是是从右向左匹配

1
2
3
4
value=www.skygroup.com
echo ${value%.*}
输出 www.skygroup.
注意因为是%是从右向左匹配,所以要写成.* 而不是*.

1.2.1.4 ${value%%pattern}

也是删除value中与pattern相匹配的部分,从右向左匹配,%与%%的区别在于贪婪模式上

  • %是非贪婪模式,也即最短匹配模式 lazy
  • %%是贪婪模式,也即最长匹配模式 greedy
1
2
3
value=www.skygroup.com
echo ${value%%.*}
输出 www

1.2.1.5 总结

  • #表示从左向右匹配,##表示从左向右贪婪匹配,删除位于#右侧通配符匹配的字符串
  • %表示从右向左匹配,%%表示从右向左贪婪匹配,删除位于%右侧通配符匹配的字符串

记忆的方法为

  • #是去掉左边(键盘上#在$的左边)
  • %是去掉右边(键盘上%在$的右边)

2. 案例

2.1 长命令行选项

背景: 在命令行中通常有两种类型的选项:短命令行选项(short options)和长命令行选项(long options)。短选项通常用于提供快速且紧凑的命令行选项,长命令行选项通常用于提供更具可读性和描述性的选项

现在需要写一个shell脚本, 可同时支持短选项和长选项,写好后使用方式如下。

  1. 短选项方式 x.sh -s csv
  2. 长选项方式 x.sh --file-suffix=csv

在shell中getopts可以很好的处理短选项,那如何处理长选项呢?

这里介绍其中一种思路,需要用到上面讲的变量扩展中关于模式扩展的知识点 ${value#pattern}

完整代码片断如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 解析命令行选项
while getopts "s:vh-:" opt; do
case $opt in
s)
file_suffix="$OPTARG"
;;
-)
case "${OPTARG}" in
file-suffix=*)
file_suffix="${OPTARG#*=}"
;;
*)
echo "unknown option: --$OPTARG" >&2
exit 1
;;
esac
;;
\?)
echo "unknown option: -$OPTARG" >&2
exit 1
;;
esac
done

假设执行的命令是 x.sh --file-suffix=csv,我们需要从命令行选项--file-suffix=csv中解析出具体的值csv,这里就用到了${value#pattern}的知识点,关键代码如下

1
file_suffix="${OPTARG#*=}"

2.2 获取不带后缀的文件名

假设获取到的文件名是 x.sh,我希望从x.sh中提取出不带后缀名的文件名,这时就用到了${value%pattern}的知识点

1
2
3
4
5
6
SHELL_NAME=x.sh
SHELL_NAME0=${SHELL_NAME%.*}
echo ${SHELL_NAME0}

输出
x

微信端的朋友也可关注我的公众号

qrcode-12cm