[03]--- Parameter Expansion, 参数扩展
$一出现,一般就是变量,命令输出,计算这几个动作。
变量名、标识一般都用{}括起来(强烈建议),${parameter}这个在有几种情况中可以很好的解决问题,比如:
VAR2=a${VAR1}b
这一类的情况等等。
${!parameter}:叫做indirect expansion,它的值是以parameter的值为变量名的变量的值。感叹号和{必须是紧挨着的。举例:
aa=b
b=c
${!aa}的值是c
用途实例是:${!prefix*} 、${!name[@]}
下面是变量扩展的表达式,有几点说明:
下面的单词word是经过tilde expansion, parameter expansion,command substitution, andarithmetic expansion之后的结果。 在word进行扩展之前,下面式子中,若带有冒号:,那么bash检查parameter是否是unset/null的。若不带冒号:,那么bash仅仅检查parameter是否是unset的。
(1)${parameter:−word}
若parameter是unset或null的,值是word的扩展;否则是parameter的值。
举例:parameter设为abcdeabcde,word是dadada
# var=abcdeabcde
# echo "${var:-dadada} ,${var-dadada}" abcdeabcde , abcdeabcde
# var=
# echo "${var:-dadada} ,${var-dadada}" dadada ,
# unset var
# echo "${var:-dadada} ,${var-dadada}" dadada , dadada
(2)${parameter:=word}
若parameter是unset或null的,值是word的扩展,且把该值赋值给parameter;否则是parameter的值。
(3)${parameter word}
若parameter是unset或null的,向stderr输出word的扩展(若word为空串,则输出一段shell定义的message),且若shell不是交互的会退出shell;否则是parameter的值。
举例:parameter设为abcdeabcde,word是dadada
#var=abcd # echo${var dadada} abcd
# var=
# echo${var dadada} -bash:var: dadada # echo${var } -bash:var: parameter null or not set
(4)${parameter:+word}
若parameter是unset或null的,值是NULL;否则值是word的扩展。
(5)${parameter ffset}、${parameter ffset:length}
Parameter的第offset(整数是从左,负数是从右,注意:和-之间要有空格)个字符开始,长度length(必须大于等于0)的字串,若:length没有,那么直到末尾。
若${array[@] ffset:length},指第offset个元素开始,length个数组元素。特殊情况是:
${@ ffset:length}、${* ffset:length}用于位置参数$1、$2等。
(6)${!prefix*}、${!prefix@}
值是那些名字以prefix开头的变量的名字,以IFS第一个值为分割符。
# echo${!a*} a a1 a2a3 aa
# echo${!a@} a a1 a2a3 aa
(7)${!name[@]}、${!name}
若name是数组,扩展成数组索引列表;
若name不是数组,若是set的,那么值是0;否则是null
#a=(1 23 4 5) # echo${!a[@]} 0 1 2 34 # unseta # echo${!a[@]} 空
# a=
# echo${!a[@]} 0
# a=100
# echo${!a[@]} 0
(8)${#parameter}
parameter的长度
(9)${parameter#word}、${parameter##word}
其中word扩展成是类似路径扩展的pattern。
若pattern匹配parameter的开头,那么${parameter#word}是删去最短匹配后剩下的串,${parameter##word}是删去最长匹配后剩下的串。
若parameter是@ 或*,那么作用在每个位置参数上;
若parameter是array[@] 或array,那么作用在每个数组元素上;
举例:
#a=abcde # echo${a#ab*} 删除最短的 cde
# echo${a##ab*} 删除最长的 空
# echo${a#?b*} 删除最短的 cde
# echo${a##?b*} 删除最长的
# echo${a##b*} 不匹配开头 abcde
# echo${a##bcd} 不匹配开头 abcde
(10)${parameter%word}、${parameter%%word}
这二者和上面的相似,#指从parameter的开头匹配,%指从末尾匹配。
一个%是指最短,2个%指最长。
(11)${parameter/pattern/string}
匹配最长的字串。
${parameter/pattern/string}替换第一个
${parameter//pattern/string}:pattern以/开头,替换所有
${parameter/#pattern/string}:pattern以#开头,必须匹配开头。
${parameter/%pattern/string}:pattern以%开头,必须匹配末尾。
${parameter/pattern}:删除匹配的字串。
若parameter是@ 或*,那么作用在每个位置参数上;
若parameter是array[@] 或array,那么作用在每个数组元素上;
实验方法:parameter设为abcdeabcde,pattern设为ab,cd,de,三种情况,string设为111。
# var=abcdeabcde
# echo"${var/ab/111} , ${var/cd/111} , ${var/de/111}" 111cdeabcde, ab111eabcde , abc111abcde
# echo"${var//ab/111} , ${var//cd/111} , ${var//de/111}" 111cde111cde, ab111eab111e , abc111abc111
# echo"${var/#ab/111} , ${var/#cd/111} , ${var/#de/111}" 111cdeabcde, abcdeabcde , abcdeabcde
# echo"${var/%ab/111} , ${var/%cd/111} , ${var/%de/111}" abcdeabcde, abcdeabcde , abcdeabc111
# echo"${var//#ab/111} , ${var//#cd/111} , ${var//#de/111}" abcdeabcde, abcdeabcde , abcdeabcde
# echo"${var//%ab/111} , ${var//%cd/111} , ${var//%de/111}" abcdeabcde, abcdeabcde , abcdeabcde
# echo"${ var /ab} , ${ var /cd} , ${ var /de}" cdeabcde, abeabcde , abcabcde
# echo"${ var //ab} , ${ var //cd} , ${ var //de}" cdecde, abeabe , abcabc
# echo"${ var /#ab} , ${ var /#cd} , ${ var /#de}" cdeabcde, abcdeabcde , abcdeabcde
# echo"${ var /%ab} , ${ var /%cd} , ${ var /%de}" abcdeabcde, abcdeabcde , abcdeabc
这个在http://man.cx/bash(1)/zh_cn#heading14这里面版本的中文man bash把双斜杠和单斜杠放在一个等级上了,其实他属于pattern包含/、#或%三种情况中的一种而已。
(12)
${parameterˆpattern}、${parameterˆˆpattern}
${parameter,pattern}、${parameter,,pattern}
^符号:匹配的子串小写转大写
,符号:匹配的子串大写转小写
^^和,,是转换所有,单个的是转换第一个字符。
若parameter是@ 或*,那么作用在每个位置参数上;
若parameter是array[@] 或array,那么作用在每个数组元素上;
实验方法:parameter设为abcdeabcde,pattern设为ab,cd,de,逗号和^类似。
#var=abcdeabcde # echo"${var^a}, ${var^b}, ${var^e}" Abcdeabcde, abcdeabcde, abcdeabcde
# echo "${var^^a}, ${var^^b}, ${var^^e}"
AbcdeAbcde, aBcdeaBcde, abcdEabcdE
# echo${var^abc} 只能匹配单个字符 abcdeabcde
# echo"${var^a*}, ${var^a?}, ${var^^a*}, ${var^^a?}" Abcdeabcde, abcdeabcde, AbcdeAbcde, abcdeabcde
# echo"${var^[abcd]}, ${var^^[abcd]}" Abcdeabcde, ABCDeABCDe
这个功能学的有点蒙,manpage里面说的太过简略,我试的好多都不是想要的结果输出。
这些个变量扩展,好多书都没提到过,不知道什么愿意,我现在看得《bash cookbook》倒是提到一些,但只是一部分。不知道是不是有版本兼容之类的问题?求大神指点。
另外,这里面好多用的pattern,manpage里面说:
The patternis expanded to produce a pattern just as in pathname expansion.
只是相似,不过还是有写的区别的,这个不是很清楚,还有在下面几种情况下:
grep ‘pattern’ *
find $MYPATH -name 'pattern'
[[ var==pattern ]]
应该还有好多,暂时想不起来了。
问题是: 这种情况的模式匹配和路径扩展(即通配符)有什么区别?求大神指点。
|