shell里的小括号,大括号结构和有括号的变量,命令的用法如下:
1.${var}
2.$(cmd)
3.()和{}
4.${var:-string},${var:+string},${var:=string},${var:?string}
5.$((exp))
6.$(var%pattern),$(var%%pattern),$(var#pattern),$(var##pattern)
1、单小括号()
(1)、命令组:$(cmd;cmd2;cmd3) 括号中的命令将会新开一个子shell顺序执行,括号中多个命令之间分号分隔,最后一个命令可以无分号
(2)、命令替换:$(cmd) 等同于`cmd`
(3)、用户初始化数组:array=(a b c d)
2、双小括号(())
(1)、整数扩展:扩展计算是整数型的计算,不支持浮点型。
(2)、只要括号中的运算符、表达式符合C语言运算规则,都可用在$((exp))中,甚至是三目运算符
(3)、单纯用 (( )) 也可重定义变量值,比如 a=5; ((a++)) 可将 $a 重定义为6
(4)、常用于算术运算比较:
如 for((i=0;i<5;i++)), 如果不使用双括号, 则为for i in `seq 0 4`或者for i in {0..4}。再如可以直接使用if (($i<5)), 如果不使用双括号, 则为if [ $i -lt 5 ]
花括号
3、花括号
(1)、大括号扩展:
如 touch {a,b}.txt 结果为a.txt b.txt。第二种:对大括号中以点点(..)分割的顺序文件列表起拓展作用,如:touch {a..d}.txt 结果为a.txt b.txt c.txt d.txt
(2)、几种特殊的替换结构:
${var:-string}、${var:+string}、${var:=string}、${var:?string}
1、若变量var为空,则用在命令行中用string来替换${var:-string},否则变量var不为空时,则用变量var的值来替换${var:-string}
如:
echo $newvar
echo ${newvar:-a}
a
echo $newvar 【变量newvar的值仍然是空,故上一命令行中${newvar:-a}被替换成了a】
newvar=b
echo ${newvar:-a} 【变量newvar的值不为空时,故此命令行中的${newvar:-b}被替换为$newvar,即b】
b
2、对于${var:=string}的替换规则和${var:-string}是一样的,所不同之处是${var:=string}若var为空时,用string替换${var:=string}的同时,把string赋给变量var:
【${var:=string}很常用的一种用法是,判断某个变量是否赋值,没有的话则给它赋上一个默认值】
echo $newvar
echo ${newvar:=a}
a
echo $newvar 【变量newvar被赋值为a,同时${newvar:=a}被替换成a】
a
echo ${newvar:=b} 【变量newvar不为空(其值已被赋为a),则${newvar:=b}被替换为newvar的值(即a)】
a
echo $newvar
a
3、${var:+string}的替换规则和上面的相反,即只有当var不是空的时候才替换成string,若var为空时则不替换或者说是替换成变量 var的值,即空值。(因为变量var此时为空,所以这两种说法是等价的)
echo $newvar
a
echo ${newvar:+b}
b
echo $newvar
a
newvar=
echo ${newvar:+b}
4、${var:?string}替换规则为:若变量var不为空,则用变量var的值来替换${var:?string};若变量var为空,则把string输出到标准错误中,并从脚本中退出。我们可利用此特性来检查是否设置了变量的值。
newvar=
echo ${newvar:?没有设置newvar的值}
bash: newvar: 没有设置newvar的值
newvar=a
echo ${newvar:?没有设置newvar的值}
a
5、补充扩展:在上面这五种替换结构中string不一定是常值的,可用另外一个变量的值或是一种命令的输出。
echo ${var:-`date`}
日 3月 6 02:10:39 CST 2005
echo ${var:-$(date)}
日 3月 6 02:11:46 CST 2005
a=test
echo ${var:-$a}
test
四种模式匹配替换结构
# 去掉左边(在键盘上#在$的左边)
% 去掉右边(在键盘上%在$的右边)
#和%中的单一符号是最小匹配,两个相同符号是最大匹配
${var%pattern},${var%%pattern},${var#pattern},${var##pattern}
${var%pattern}:shell在var中寻找,判断是否以pattern模式结尾,如果是,就从命令行把var中内容去掉右边最短的(精简模式)匹配模式
${var%%pattern}:shell在var中寻找,判断是否以pattern模式结尾,如果是,就从命令行把var中内容去掉右边最长的(贪婪模式)匹配模式
${var#pattern}:shell在var中寻找,判断是否以pattern模式开始,如果是,就从命令行把var中内容去掉左边最短的(精简模式)匹配模式
${var##pattern}:shell在var中寻找,判断是否以pattern模式开始,如果是,就从命令行把var中内容去掉左边最长的(贪婪模式)匹配模式
结构中的pattern支持通配符,*表示零个或多个任意字符,?表示仅与一个任意字符匹配,[...]表示匹配中括号里面的字符,[!...]表示不匹配中括号里面的字符
举例:
#!/bin/bash
var=testcase
echo ${var%s*e} #结果:testca (精简模式) 删除以s*e结尾
echo ${var%%s*e} #结果:te (贪婪模式) 删除以s*e结尾
echo ${var#?e} #结果:stcase (精简模式) 删除开始到二个e
echo ${var##?e} #结果:stcase (贪婪模式) 删除开始到二个e
echo ${var##*e} #结果:为空全部匹配即全部删除
echo ${var##*s} #结果:e (贪婪模式) 删除开始到倒数第二个s
字符串提取和替换
${var:num},${var:num1:num2},${var/pattern/pattern},${var//pattern/pattern}
${var:num}:shell在var中提取第num个字符到末尾的所有字符。若num为正数,从左边0处开始;若num为负数,从右边开始提取字串,但必须使用在冒号后面加空格或一个数字或整个num加上括号,
如${var: -2}、${var:1-3}或${var:(-2)}
${var:num1:num2}:num1是位置,num2是长度。表示从$var字符串的第$num1个位置开始提取长度为$num2的子串。不能为负数
${var/pattern/pattern}:表示将var字符串的第一个匹配的pattern替换为另一个pattern
${var//pattern/pattern}:表示将var字符串中的所有能匹配的pattern替换为另一个pattern
举例:
#!/bin/bash
var=helloword
echo ${var: 2} #结果:lloword
echo ${var: -2} #结果:hellowo
echo ${var:2:3} #结果:llo
echo ${var/o/p} #结果:hellpword 将var中第一个匹配的o替换为p
echo ${var//o/p} #结果:hellpwprd 将var中所有匹配的o替换为p
分述如下:
1.Shell中变量的原形:${var}大家常见的变量形式都是$var,如
var=test
echo $var
test
但当你要显示变量值加随意的字符(我这里用AA)时,就会出错,如下:
echo $varAA
这时应该用变量的原形:${var},即是加一个大括号来限定变量名称的范围,如下
echo ${var}AA
testAA
以这个特性,我们可以很方便地写一个批量改后缀名的程序,我把它命名为mymv,程序如下:
mymv.sh
#!/bin/bash
tail=$1
for filename in `ls`
do
mv $filename ${filename}.$tail
done
程序需要提供一个后缀名,如c,表示改为后缀为c的C程序文件,看下面的测试:
ls
a b c
mymv c
ls
a.c b.c c.c
一串的命令执行:()和{}都是对一串的命令进行执行,但有所区别:
()只是对一串命令重新开一个子shell进行执行
{}对一串命令在当前shell执行
()和{}都是把一串的命令放在括号里面,并且命令之间用;号隔开
()最后一个命令可以不用分号
{}最后一个命令要用分号
{}的第一个命令和左括号之间必须要有一个空格
()里的各命令不必和括号有空格
()和{}中括号里面的某个命令的重定向只影响该命令,但括号外的重定向则影响到括号里的所有命令
#我们来看几个例子:
var=test
(var=notest; echo $var) 【变量var值为notest,此时在子shell中有效】
notest
echo $var 【父shell中值仍为test】
test
{ var=notest; echo $var;}【注意左括号和var之间要有一个空格 】
notest
echo $var 【父shell中的var变量的值变为了notest 】
notest
{ var1=test1;var2=test2;echo $var1>a;echo $var2;} 【输出test1被重定向到文件a中】
test2 【而test2输出则仍输出到标准输出中】
cat a
test1
{ var1=test1;var2=test2;echo $var1;echo $var2;}>a 【括号内命令的标准输出全部被重定向到文件a中】
cat a
test1
test2
OSIX标准的扩展计算:$((exp))这种计算是符合C语言的运算符,也就是说只要符合C的运算符都可用在$((exp)),甚至是三目运算符。
注意:这种扩展计算是整数型的计算,不支持浮点型.若是逻辑判断,表达式exp为真则为1,假则为0。
echo $((3+2))
5
echo $((3>2))
1
echo $((25<3 ? 2:3))
3
echo $var
echo $((var=2+3))
5
echo $var
5
echo $((var++))
5
echo $var
6