shell变量替换

shell变量替换

# 变量替换
b=${a/123/321};将${a}里的第一个123替换为321
b=${a//123/321};将${a}里的所有123替换为321

# 利用 ${ } 還可針對不同的變數狀態賦值(沒設定、空值、非空值): 
${file-my.file.txt} :假如 $file 沒有設定,則使用 my.file.txt 作傳回值。(空值及非空值時不作處理) 
${file:-my.file.txt} :假如 $file 沒有設定或為空值,則使用 my.file.txt 作傳回值。 (非空值時不作處理)
${file+my.file.txt} :假如 $file 設為空值或非空值,均使用 my.file.txt 作傳回值。(沒設定時不作處理)
${file:+my.file.txt} :若 $file 為非空值,則使用 my.file.txt 作傳回值。 (沒設定及空值時不作處理)
${file=my.file.txt} :若 $file 沒設定,則使用 my.file.txt 作傳回值,同時將 $file 賦值為 my.file.txt 。 (空值及非空值時不作處理)
${file:=my.file.txt} :若 $file 沒設定或為空值,則使用 my.file.txt 作傳回值,同時將 $file 賦值為 my.file.txt 。 (非空值時不作處理)
${file?my.file.txt} :若 $file 沒設定,則將 my.file.txt 輸出至 STDERR。 (空值及非空值時不作處理)
${file:?my.file.txt} :若 $file 沒設定或為空值,則將 my.file.txt 輸出至 STDERR。 (非空值時不作處理)

# tips:
以上的理解在於, 你一定要分清楚 unset 與 null 及 non-null 這三種賦值狀態.
一般而言, : 與 null 有關, 若不帶 : 的話, null 不受影響, 若帶 : 則連 null 也受影響.

Bash Shell可以进行变量的条件替换,既只有某种条件发生时才进行替换,替换 条件放在{}中
1、${value:-word}
当变量未定义或者值为空时,返回值为word的内容,否则返回变量的值.
例1:
[root@master ~]# echo ${a:-123}   #变量a未定义返回了123
123
[root@master ~]# a=10 && echo ${a:-123}      #定义变量a=10,返回10
10
 
2、${value:=word}ls
与前者类似,只是若变量未定义或者值为空时,在返回word的值的同时将word赋值给value
例2:
[root@master ~]# echo ${b:=20}  #变量b未定义,返回20并把值赋给b
20
[root@master ~]# echo $b    #可以看到,现在变量b的值为20
20
 
3、${value:?message}
若变量已赋值的话,正常输出变量的值.否则将消息message送到标准错误输出(若 此替换出现在Shell程序中,那么该程序将终止运行,则退出)
例3:
#c变量没有定义就会终止程序并输出后面设置好的提示信息
[root@master ~]# echo ${c:?变量未定义或者未赋值}  
-bash: c: 变量未定义或者未赋值
 
#变量定义了,就会输出变量的值
[root@master ~]# c=10 && echo ${c:?变量未定义或者未赋值}  
10
 
[ ${1:?用户名不能为空} ]		#此用法最好
如果变量没有值,则报错,并退出脚本,否则继续执行,不必像echo输出变量的值

4、${value:+word}
若变量已赋值的话,其值才用word替换,否则不进行任何替换
例4:
[root@master ~]# echo ${d:+12}  #可以看到变量d未赋值没有进行替换
 
[root@master ~]# d=10 && echo ${d:+12}  #给变量d赋值后进行了替换
12
 
5、${value:offset}
${value:offset:length}
从变量中提取子串,这里offset和length可以是算术表达式.,offset代表偏移量,从第几个字符开始提取,length是需要提取的字符串的个数。
例5:
[root@master ~]# e=abcdefghijk && echo ${e:3:2}  #从第3个字符后面开始提取2个字符
de
[root@master ~]# e=abcdefghijk && echo ${e:5:6}  #从第5个字符后面开始提取6个字符
fghijk
 
6、 ${#value}
变量的字符个数
例6:
[root@master ~]# f=abcde && echo ${#f}  #计算变量f的字符个数
5
 
7、${value#pattern} 和 ${value##pattern}
去掉value中与pattern相匹配的部分,条件是value的开头与pattern相匹配 #与##的区别在于一个是最短匹配模式,一个是最长匹配模式.
例7:
[root@master ~]# g="hehello heworld" && echo ${g##he}
hello heworld
[root@master ~]# g="hehello heworld" && echo ${g#he}
hello heworld
[root@master ~]# g="hehello heworld" && echo ${g##heworld}
hehello heworld
[root@master ~]# g="hehello heworld" && echo ${g#hehello}
heworld
实验证明${value#pattern} 和 ${value##pattern}没有太大区别,都只能从开头匹配,而且都只能匹配一次。
 
8、${value%pattern} 和${value%%pattern}
和上面的例7类似,只是是从value的尾部和pattern相匹配,%与%%的区别与#与##一样
例8:
[root@master ~]# h="hehello heworld" && echo ${g%heworld}
hehello
[root@master ~]# h="hehello heworld" && echo ${g%he}
hehello heworld
[root@master ~]# h="hehello heworld" && echo ${g%%he}
hehello heworld
[root@master ~]# h="hehello heworld" && echo ${g%%ld}
hehello hewor
实验证明${value%pattern} 和 ${value%%pattern}没有太大区别,都只能从结尾匹配,而且都只能匹配一次。
 
9、${value/pattern/string} 和${value//pattern/string}
进行变量内容的替换,把与pattern匹配的部分替换为string的内容,’/’与’//’的区别是’/’只进行一次匹配替换,而’//’可以进行多次匹配替换。
例9:
[root@master ~]# i="hello world" && echo ${i/wo/aa}  #这里把wo替换成为aa
hello aarld
[root@master ~]# i="hello world" && echo ${i/o/b}  #这里把一个o替换成为b
hellb world
[root@master ~]# i="hello world" && echo ${i//o/b}  #这里把两个o都替换成为b
hellb wbrld