您的位置:首页 > 运维架构 > Shell

shell变量替换

2012-03-08 13:57 148 查看
变量替换:

一:简单赋值和替换

a=bcd

$ echo $a  

bcd

$ echo ${a}

bcd

二:变量扩充

除了shell中的meta,其它的[^a-zA-Z0-9_]几乎都可以作单词边界。

同sed中关于单词边界[^a-zA-Z0-9_]的描述。

这些功能有时候会在程序中有意想不到的作用!

例如:

$ a=bcd

$ echo ${a}.b

bcd.b

$ echo $a.php

bcd.php

$ echo $a%b

bcd%b

$ echo /$a/bc

/bcd/bc

对于shell中的meta字符,则backslash。

$ echo $a\*b

bcd*b

三:变量中的变量

$ a=bcd

$ b=efg

$ c=$a$b

$ echo $c

bcdefg

$ d=$c.ghi

$ echo $d

bcdefg.ghi

思考:若变量互相嵌套,会怎样呢?

四:变量的特异功能

到网中人的啦!(ps:重写真是没激情啊)

file=/dir1/dir2/dir3/my.file.txt

我们可以用 ${ } 分别替换获得不同的值:

${file#*/}:从变量file的字符串左边开始,删除字符直到第一个“/”:dir1/dir2/dir3/my.file.txt

${file##*/}:从变量file的字符串左边开始,删除字符直到最后一个“/”:my.file.txt

${file#*.}:从变量file的字符串左边开始,删除字符直到第一个“.”:file.txt

${file##*.}:从变量file的字符串左边开始,删除字符直到最后一个“.”:txt

其实,在“#”后面,无非就是一个匹配问题,不限于两个,你可以放任意个字符,还可以用shell中另外的通配符“?”“[…]”“[!…]”,例如:

$ echo ${file#????}

1/dir2/dir3/my.file.txt

$ echo ${file#*[0-9]}

/dir2/dir3/my.file.txt

$ echo ${file#/dir1/dir[0-9]}

/dir3/my.file.txt

“#”:相当于最小匹配,遇到一个最小的符合其后表达式的字符串(单个或多个)即中止匹配动作;

“##”:相当于最大匹配,它尽可能的匹配更多的字符。

我们可以拿“*”来说明:  

*  在shell中表示匹配任何符号包括空。当它在只有一个 # 的变量替换中,受最小匹配的影响,它不会匹配任何可打印字符,只匹配一个空,也就是什么也不匹配,你完全可以忽略它的存在;

当在有两个 ## 的变量替换中,受最大匹配的影响,一个 * 表示匹配整个字符串。

如果想匹配字符“*”时,要在“*”前加一个“\”,其后的“*”失去通配符的功能。

但是还有一种例外情况(请接着看)

例:

$ file2=abcd.efgh.ijkl.oopp

$ echo ${file2#*.*.*.*}

$ echo ${file2##*.*.*.*}

想想上面两个的输出是什么?

$ echo ${file2#*.*.*.*}

oopp

$ echo ${file2##*.*.*.*}



??知道为什么吗?因为:“*”匹配任何符号包括空。遇到一个“#”时,最后一个“*”就匹配“空”去了。看下面的:

$ echo ${file2#*.*.*.?}

opp

$ echo ${file2#*.*.*.?*}

opp

$ echo ${file2##*.*.*.?}

opp

$ echo ${file2##*.*.*.?*}



do you know?

$ echo $file3

*ab*de*cd

看看下面将输出什么?

$ echo ${file3#*ab}       

*de*cd

$ echo ${file3#**}

*ab*de*cd

$ echo ${file3##**}



$ echo ${file3#\*ab}

*de*cd

$ echo ${file3#\**}

ab*de*cd

$ echo ${file3##\**}



$ echo ${file3#*a}

b*de*cd

$ echo ${file3#\*a}

b*de*cd

不知各位有没有发现,“*”在一个“#”中时,并不一定代表“空”,它可能代表一个字符“*”也可能代表其他的什么字符,如上例的:

“$ echo ${file3#*a}”输出为“b*de*cd”,其实这还是符合最小匹配理论的。这个表达式的意思是:从变量file3的字符串左边开始删除字符,直到遇到第一个字符“a”。所以不要和“$ echo ${file3#\*a}”混淆,虽然两个结果是一样,但意思是不一样的。

再举几个例子,相信大家更容易理解这段话:

$ echo $file3

*ab*de*cd*ab*de                     //注意:出现两个“*ab”

$ echo ${file3#*a}

b*de*cd*ab*de                         //删除字符,直到出现第一个“a”,“*”为通配符

$ echo ${file3##*a}

b*de                                           //删除字符,直到出现第二个“a”,“*”为通配符

$ echo ${file3##\*a}

b*de*cd*ab*de                         //删除字符串“*a”,“*”在“\”表示字符“*”

除了通配符“*”比较难理解一点,其他的shell通配符就都很容易了。

至于“%”,和“#”不同的地方,就是从变量字串右部开始。

${file%/*}:从右部开始拿掉字符,直到遇到(从右部数起的)第一个“/” :/dir1/dir2/dir3

${file%%/*}:从右部开始拿掉字符,直到遇到(从右部数起的)最后一个“/”:(空值)

${file%.*}:从右部开始拿掉字符,直到遇到(从右部数起的)第一个“.”:/dir1/dir2/dir3/my.file

${file%%.*}:从右部开始拿掉字符,直到遇到(从右部数起的)最后一个“.”:/dir1/dir2/dir3/my

变量替换: ${variablename} 显示变量名

Bash Shell可以进行变量的条件替换,既只有某种条件发生时才进行替换,替换 

条件放在{}中. 

(1) ${value:-word} 

当变量未定义或者值为空时,返回值为word的内容,否则返回变量的值. 

(2) ${value:=word} 

与前者类似,只是若变量未定义或者值为空时,在返回word的值的同时将 

word赋值给value 

(3) ${value:?message} 

若变量以赋值的话,正常替换.否则将消息message送到标准错误输出(若 

此替换出现在Shell程序中,那么该程序将终止运行) 

(4) ${value:+word} 

若变量以赋值的话,其值才用word替换,否则不进行任何替换 

 (5) ${value:offset} 

${value:offset:length} 

从变量中提取子串,这里offset和length可以是算术表达式. 

 (6) ${#value} 

变量的字符个数 

 (7) ${value#pattern} 

${value##pattern} 

去掉value中与pattern相匹配的部分,条件是value的开头与pattern相匹配 

#与##的区别在于一个是最短匹配模式,一个是最长匹配模式. 

 (8) ${value%pattern} 

${value%%pattern} 

于(7)类似,只是是从value的尾部于pattern相匹配,%与%%的区别与#与##一样 

(9) ${value/pattern/string} 

${value//pattern/string} 

进行变量内容的替换,把与pattern匹配的部分替换为string的内容,/与//的区 

别与上同 

4000
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  shell file string c