Bash扩展
Contents
Bash扩展
Bash支持如下扩展:大括号扩展、波浪号扩展、参数和变量扩展、算术扩展、命令替换、单词拆分、文件名扩展。它们按照顺序依次进行扩展。
大括号扩展具有如下样式:preamble{str,str,str|start..end..[..incr]}postscript
一个前缀,大括号中的一系列逗号分隔的字符串或者一个序列表达式,以及一个后缀。前后缀与括号中的每个项目分别匹配,大括号扩展是可以嵌套的。举例如下:
|
|
序列表达式的start和end可以都是整数或者单个字符,可选增量是一个整数,序列包括头尾。如果start和end中任何一个是整数并且以0开头,那么产生的数字将有同样的宽度,不够用前导0补齐(此特性仅在bash中有效,sh无效)。
在Shell的所有扩展中大括号扩展(brace expansion)是第一实施的,执行的严格的文本替换,特别是不进行变量扩展。因为像 {0..$END}
这种语句不会执行期望的扩展。${
一定不会被当做大括号扩展。括号中出现的{``,
需要用反斜杠来转义。
括号中不允许有任何空格,除非被引用或转义。去掉一下语句中任何一个转义符看看结果:
|
|
波浪号扩展(tilde expansion):如果一个单词以~
头,那么~
直到/
被称为波浪前缀(tilde-prefix)。
|
|
变量扩展(shell parameter expansion):变量扩展以$
字符后接变量名,可以在变量名两边包裹大括号,形如${var}
,只有当变量名为位置变量(postional parameter)并且大于等于10时大括号是必须的,或者后面紧接着别的字符时也是必须的。变量扩展中${!var}
形式称为间接变量(indirect parameter),其中var的值作为新的变量名,再取新变量的值。
以下形式的变量扩展,其中 word 可以是波浪扩展、变量扩展、命令替换以及算术扩展表达式。如果有冒号,将同时检查 parameter 是否存在以及是否为空串,如果没有冒号,将只检查 paramter 是否存在。(在bash中空串与null含义相同)。
${parameter:-word}
如果parameter不存在或为null,取word的值,否则取parameter本身的值;${parameter:=word}
如果parameter不存在或为null,word的值赋给parameter,然后取其值,否则取parameter本身的值;${parameter:?word}
如果parameter不存在或为null,word值被写入到标准误,然后退出脚本,否则取parameter本身的值;${parameter:+word}
如果parameter不存在或为null,不做任何替换,否则取word的值;${parameter:offset}
${parameter:offset:length}
被扩展为选取parameter字符串中从offset开始,length长度的子字符串,也被称为子字符串扩展(substring expansion)。如果parameter是位置变量或者数组,length为元素的个数,offset为元素起始位置。在三种情况下,offset如果是负数表示从尾部计算,length如果为负数表示结束点从尾部计算的位置。(offset和length支持负数的特性仅在bash中有效);${!prefix*}
${!prefix@}
扩展为以prefix为前缀的变量名列表;${#parameter}
扩展为变量值的长度,如果parameter是*
或者@
则为位置变量的数目,如果是数组则为数组的元素个数;
|
|
${parameter#word}
${parameter##word}
从parameter的头部删除掉匹配word的子字符串,返回剩余部分,#匹配最短,##匹配最长。如果parameter是*
或者@
或数组,则对里边的每个变量应用一次;
|
|
${parameter%word}
${parameter%%word}
与#方式反过来,匹配尾部,并删除字符串,返回剩余部分。%匹配最短,%%匹配最长。如果parameter是*
或者@
或数组,则对里边的每个变量应用一次;
|
|
${parameter/pattern/string}
从parameter值中匹配pattern并替换为string,默认只替换第一个,如果pattern以/
开始则替换所有,如果pattern以#
开头,则必须匹配parameter的开头部分,如果pattern以%
则必须比配parameter的结尾部分。如果没有string部分,则执行匹配删除。如果parameter是*
或者@
或数组,则对里边的每个变量应用一次;${parameter^pattern}
${parameter^^pattern}
${parameter,pattern}
${parameter,,pattern}
对parameter的值执行匹配并更换大小写。匹配原则是parameter中的每个字符与pattern进行匹配,因而,pattern必须是单个字符的模式。^
将首字母小写转为大写,^^
将全部小写转大写,,
将首字母大写转为小写,,,
将全部大写转小写。如果省略pattern,则匹配整个字符串。如果parameter是*
或者@
或数组,则对里边的每个变量应用一次;
命令替换(command substitution):将命令的输出替换命令本身。形式:$(command)
或 `command`
。推荐使用新式的 $()
形式,因为旧式的反引号形式不容易嵌套命令,并且对 \ ' $
需要特殊处理。$(cat file)
与$(<file)
结果一样。
算术扩展(arithmetic expansion)引用bash中出现算术表达式,形如:$(( expression ))
算术扩展的变量可以是变量扩展、命令扩展的结果。
单词拆分(word splitting):对于没有在引号中的字符串先取出头尾的空白符再进行单词拆分。单词拆分以 $IFS
中的每个字符进行分割,默认 IFS
是 <space><tab><newline>
,改变 IFS
的值会改变单词分割的方式,特别是当 IFS
为空字符串时不进行单词拆分。显式的空字符串 ""
''
会被保留,但是没有引号的空字符串会被忽略。
文件名扩展(filename expansion)是Bash扩展中的最后一个,当非引号中的字符串含有 * ? [
时就以此为模式进行文件名匹配,返回排好序的文件名列表;在文件名扩展中,. /
两个字符不是特殊字符。
*
匹配所有字符串包括空字符串;?
匹配单个字符;[...]
匹配单个字符,跟常用的正则一样的,要匹配-
]
^
时,]
放在头部,^
-
放在尾部,还有一种[:class:]
的形式来指定一族字符;[:alnum:]
匹配所有字母和数字字符,相当于A-Za-z0-9
[:alpha:]
匹配所有字母,相当于A-Za-z
[:ascii:]
匹配所有ASCII字符[:blank:]
匹配空格和tab[:digit:]
匹配所有数字0-9
[:word:]
匹配所有字母数字下划线[A-Za-z0-9_]
[:punct:]
匹配所有标点符号[:cntrl:]
匹配控制字符(ASCII 0-31)[\x00-\x1F\x7F]
[:graph:]
匹配可打印字符(ASCII 32-126),剔除空格[:lower:]
匹配小写字母a-z
[:upper:]
匹配大写字母A-Z
[:print:]
匹配可打印字符,包括空格[:space:]
匹配所有空白符,包括换行符[:xdigit:]
匹配十六进制数字0-9A-Fa-f
以上的 character classes 必须放在中括号中;
参考阅读:
- POSIX Bracket Expressions
- BOOK: Bash Reference Manual
- BOOK: BASH 中文文档
- BOOK: Advanced Bash-Scripting Guide
Author zoro.wang
LastMod 2017-07-25