0


【Linux】总结shell 中各种括号的用法 () (())、[]、[[]]、{}

文章目录

本文旨在总结shell 中各种括号的作用,以及使用场景等。

shell 中常见的括号有以下几种,我会分别讲解各个符号的作用。

()(())、[]、[[]]、{}

1. ()用法

1.1 命令替换 $()

为什么叫命令替换,不直接叫表达式赋值语法呢?

注意:括号前有个$符号,并且括号的内容必须是shell命令,可以携带参数,即可以直接在linux 的cmd命令行执行

命令就是将

shell命令

的输出赋给变量,它是脚本编程中的一个主要组成部分。

 $ date2022年 02月 28日 星期一 15:34:24 CST
 $ test=$(date)
 $ echo$test2022年 02月 28日 星期一 15:34:34 CST
 $

除了使用$() 进行命令替换以外,还可以用 `` 符号。 注意在美式键盘上,它通常和波浪线( ~)位于同一键位。

$ test2=`date`
 $ echo$test22022年 02月 28日 星期一 15:36:50 CST

1.2 命令分组

我们知道可以 把多条命令放在一起执行,并通过;分号进行分割命令,这个方式叫做命令列表

命令分组就是在多命令基础上,额外多了括号,例如 (cmd1;cmd2;cmd3)

注意 命令分组

括号中的命令将会新开一个子shell顺序执行,所以括号中的变量不能够被脚本余下的部分使用。括号中多个命令之间用分号隔开,最后一个命令可以没有分号,各命令和括号之间不必有空格。

 $ (pwd ;ls;echo$BASH_SUBSHELL)
/Data2/Team/huangtianbao/learn/source/test
123  tests.c
1
 $ pwd;ls;echo$BASH_SUBSHELL
/Data2/Team/huangtianbao/learn/source/test
123  tests.c
0

1.3 用于初始化数组

在shell 中也是支持定义数组的,数组的赋值是通过()括起来的,数组元素之间通过空格分隔,并且数组的下标是从零开始的。其中和其他编译语言一样要访问数组元素需要通过数组名+[下标]的方式访问。[*] 比较特别,它可以列出数组的所有元素。并且变量名指代的是数组变量的第一个元素也就是[0]。

 $ test=(a b c d)
 $ echo${test[*]}
 a b c d
 $ echo${test[0]}
 a
 $ echo$test
 a

2 (())用法

2.1 对整数进行数学运算

双小括号 (( )) 是 Bash Shell 中专门用来进行整数运算的命令,它的效率很高,写法灵活,是企业运维中常用的运算命令。

注意:(( )) 只能进行整数运算,不能对小数(浮点数)或者字符串进行运算。后续讲到的 bc 命令可以用于小数运算。

双括号命令的格式如下:

(( expression ))
  • 通俗地讲,就是将数学运算表达式放在(())之间。

  • 表达式可以只有一个,也可以有多个,多个表达式之间以逗号,分隔。对于多个表达式的情况,以最后一个表达式的值作为整个 (( )) 命令的执行结果

  • 可以使用 $ 获取 (( )) 命令的结果,这和使用$获得变量值是类似的。

    表1:(( )) 的用法
    运算操作符/运算命令 说明 ((a=10+66)

((b=a-15))
((c=a+b)) 这种写法可以在计算完成后给变量赋值。以 ((b=a-15)) 为例,即将 a-15 的运算结果赋值给变量 c。

注意,使用变量时不用加

$

前缀,(( )) 会自动解析变量名。 a=$((10+66)
b=$((a-15))
c=$((a+b)) 可以在 (( )) 前面加上

$

符号获取 (( )) 命令的执行结果,也即获取整个表达式的值。以 c=$((a+b)) 为例,即将 a+b 这个表达式的运算结果赋值给变量 c。

注意,类似 c=((a+b)) 这样的写法是错误的,不加

$

就不能取得表达式的结果。 ((a>7 && b==c)) (( )) 也可以进行逻辑运算,在 if 语句中常会使用逻辑运算。 echo $((a+10)) 需要立即输出表达式的运算结果时,可以在 (( )) 前面加

$

符号。 ((a=3+5, b=a+10)) 对多个表达式同时进行计算。
在 (( )) 中使用变量无需加上$前缀,(( )) 会自动解析变量名,这使得代码更加简洁,也符合程序员的书写习惯。

除了支持简单的加减乘除外,还支持:
在这里插入图片描述
实例演示:

【实例1】利用 (( )) 进行简单的数值计算。

[c.biancheng.net]$ echo$((1+1))2[c.biancheng.net]$ echo$((6-3))3[c.biancheng.net]$ i=5[c.biancheng.net]$ ((i=i*2))#可以简写为 ((i*=2))。[c.biancheng.net]$ echo$i#使用 echo 输出变量结果时要加 $。10

【实例2】用 (( )) 进行稍微复杂一些的综合算术运算。

[c.biancheng.net]$ ((a=1+2**3-4%3))[c.biancheng.net]$ echo$a8[c.biancheng.net]$ b=$((1+2**3-4%3))#运算后将结果赋值给变量,变量放在了括号的外面。[c.biancheng.net]$ echo$b8[c.biancheng.net]$ echo$((1+2**3-4%3))#也可以直接将表达式的结果输出,注意不要丢掉 $ 符号。8[c.biancheng.net]$ a=$((100*(100+1)/2))#利用公式计算1+2+3+...+100的和。[c.biancheng.net]$ echo$a5050[c.biancheng.net]$ echo$((100*(100+1)/2))#也可以直接输出表达式的结果。5050

【实例3】利用 (( )) 进行逻辑运算。

[c.biancheng.net]$ echo$((3<8))#3<8 的结果是成立的,因此,输出了 1,1 表示真1[c.biancheng.net]$ echo$((8<3))#8<3 的结果是不成立的,因此,输出了 0,0 表示假。0[c.biancheng.net]$ echo$((8==8))#判断是否相等。1[c.biancheng.net]$ if((8>7&&5==5))>then>echoyes>fiyes

最后是一个简单的 if 语句的格式,它的意思是,如果 8>7 成立,并且 5==5 成立,那么输出 yes。显然,这两个条件都是成立的,所以输出了 yes。

【实例4】利用 (( )) 进行自增(++)和自减(–)运算。

[c.biancheng.net]$ a=10[c.biancheng.net]$ echo$((a++))#如果++在a的后面,那么在输出整个表达式时,会输出a的值,因为a为10,所以表达式的值为10。10[c.biancheng.net]$ echo$a#执行上面的表达式后,因为有a++,因此a会自增1,因此输出a的值为11。11[c.biancheng.net]$ a=11[c.biancheng.net]$ echo$((a--))#如果--在a的后面,那么在输出整个表达式时,会输出a的值,因为a为11,所以表达式的值的为11。11[c.biancheng.net]$ echo$a#执行上面的表达式后,因为有a--,因此a会自动减1,因此a为10。10[c.biancheng.net]$ a=10[c.biancheng.net]$ echo$((--a))#如果--在a的前面,那么在输出整个表达式时,先进行自增或自减计算,因为a为10,且要自减,所以表达式的值为9。9[c.biancheng.net]$ echo$a#执行上面的表达式后,a自减1,因此a为9。9[c.biancheng.net]$ echo$((++a))#如果++在a的前面,输出整个表达式时,先进行自增或自减计算,因为a为9,且要自增1,所以输出10。10[c.biancheng.net]$ echo$a#执行上面的表达式后,a自增1,因此a为10。10

本教程假设读者具备基本的编程能力,相信读者对于前自增(前自减)和后自增(后自减)的区别也非常清楚,这里就不再赘述,只进行简单的说明:
执行 echo $((a++)) 和 echo $((a–)) 命令输出整个表达式时,输出的值即为 a 的值,表达式执行完毕后,会再对 a 进行 ++、-- 的运算;
而执行 echo $((++a)) 和 echo $((–a)) 命令输出整个表达式时,会先对 a 进行 ++、-- 的运算,然后再输出表达式的值,即为 a 运算后的值。

【实例5】利用 (( )) 同时对多个表达式进行计算

[c.biancheng.net]$ ((a=3+5, b=a+10))#先计算第一个表达式,再计算第二个表达式[c.biancheng.net]$ echo$a$b818[c.biancheng.net]$ c=$((4+8, a+b))#以最后一个表达式的结果作为整个(())命令的执行结果[c.biancheng.net]$ echo$c26

2.2 逻辑运算

这里单独把逻辑运算列出来,是为了强调 (()) ,成立 输出1,不成立输出0,这个和 []、[[]]是反过来的

【实例3】利用 (( )) 进行逻辑运算。

[c.biancheng.net]$ echo$((3<8))#3<8 的结果是成立的,因此,输出了 1,1 表示真1[c.biancheng.net]$ echo$((8<3))#8<3 的结果是不成立的,因此,输出了 0,0 表示假。0[c.biancheng.net]$ echo$((8==8))#判断是否相等。1[c.biancheng.net]$ if((8>7&&5==5))>then>echoyes>fiyes

3 中括号、方括号[]

3.1 字符串和数值比较 []

if[ condition ]then
commands
fi

等价于

iftest  condition 
then
commands
fi

test命令可以判断三类条件:
数值比较
字符串比较
文件比较

3.2 用于正则表达式

字符范围。用作正则表达式的一部分,描述一个匹配的字符范围。作为if [] 用途的中括号内不能使用正则。

示例:
使用了中括号以及在特定位置上可能出现的两种字符: 1或3。中括号表示一个字符位置并给出多个可能的选择。可以像上面的例子那样将待选的字符列出来,也可以指定字符范围,例如字母范围[1–3]。

$ ls123223323  tests.c
$ ls[13]*
123323
$ ls[1-3]*
123223323

3.3 数学运算$[]

一般数学运算可以用,expr 命令但是expr 命令会有缺点,它在处理一些特定字符会出现问题,例如 “ * ”星号符 。在遇到特俗符号时需要使用shell的转义字符(反斜线)将其标出来。

$ expr1 + 56
$ expr5 * 2
expr: syntax error
$ expr5\* 210

用方括号执行shell数学运算比用expr命令方便很多。在使用方括号来计算公式时,不用担心shell会误解乘号或其他符号。 shell知道它不是通配符,因为它在方括号内。bash shell数学运算符只支持整数运算。若要进行任何实际的数学计算,这是一个巨大的限制。

$ var1=$[1 + 5]
$ echo$var16
$ var2=$[$var1 * 2]
$ echo$var212
 $ var1=100
 $ var2=45
 $ var3=$[$var1 / $var2]
 $ echo The final result is $var3
 The final result is 2

4. { }用法

4.1 变量范围限定${}

根据下面的shell 命令可见 如果变量 a 没有用{} 括起来的话,shell 就会将abc 识别为变量名。这显然不是我们想要的结果

 $ a=123456
 $ echo$abc

 $ echo${a}bc
123456bc
 $

4.2 命令分组 { ;;}

注意

“{” 后面需要有空格,“}” 前可以不需要空格

但是最后一条命令需要结束后也需要加“;” 。可以看到echo $BASH_SUBSHELL 输出的为 0,说明命令分组 { ;;} 并没有创建子shell 执行命令。

$ {ls;ls;echo$BASH_SUBSHELL;}123223323  tests.c
123223323  tests.c
0

4.3 用于通配符

将对大括号中的文件名做扩展。在大括号中,不允许有空白,除非这个空白被引用或转义。第一种:对大括号中的以逗号分割的文件列表进行拓展。如 touch {a,b}.txt 结果为a.txt b.txt。第二种:对大括号中以点点(…)分割的顺序文件列表起拓展作用,如:touch {a…d}.txt 结果为a.txt b.txt c.txt d.txt

# ls {ex1,ex2}.sh 
ex1.sh ex2.sh 
# ls {ex{1..3},ex4}.sh 
ex1.sh ex2.sh ex3.sh ex4.sh 
# ls {ex[1-3],ex4}.sh 
ex1.sh ex2.sh ex3.sh ex4.sh

4.4 几种特殊的替换结构

${var:-string},${var:+string},${var:=string},${var:?string}

      v 
     
    
      a 
     
    
      r 
     
    
      : 
     
    
      − 
     
    
      s 
     
    
      t 
     
    
      r 
     
    
      i 
     
    
      n 
     
    
      g 
     
    
   
     和 
    
   
  
    {var:-string}和 
   
  
var:−string和{var:=string}:若变量var为空,则用在命令行中用string来替换 
 
  
   
    
    
      v 
     
    
      a 
     
    
      r 
     
    
      : 
     
    
      − 
     
    
      s 
     
    
      t 
     
    
      r 
     
    
      i 
     
    
      n 
     
    
      g 
     
    
   
     ,否则变量 
    
   
     v 
    
   
     a 
    
   
     r 
    
   
     不为空时,则用变量 
    
   
     v 
    
   
     a 
    
   
     r 
    
   
     的值来替换 
    
   
  
    {var:-string},否则变量var不为空时,则用变量var的值来替换 
   
  
var:−string,否则变量var不为空时,则用变量var的值来替换{var:-string};对于 
 
  
   
    
    
      v 
     
    
      a 
     
    
      r 
     
    
      : 
     
    
      = 
     
    
      s 
     
    
      t 
     
    
      r 
     
    
      i 
     
    
      n 
     
    
      g 
     
    
   
     的替换规则和 
    
   
  
    {var:=string}的替换规则和 
   
  
var:=string的替换规则和{var:-string}是一样的,所不同之处是 
 
  
   
    
    
      v 
     
    
      a 
     
    
      r 
     
    
      : 
     
    
      = 
     
    
      s 
     
    
      t 
     
    
      r 
     
    
      i 
     
    
      n 
     
    
      g 
     
    
   
     若 
    
   
     v 
    
   
     a 
    
   
     r 
    
   
     为空时,用 
    
   
     s 
    
   
     t 
    
   
     r 
    
   
     i 
    
   
     n 
    
   
     g 
    
   
     替换 
    
   
  
    {var:=string}若var为空时,用string替换 
   
  
var:=string若var为空时,用string替换{var:=string}的同时,把string赋给变量var:${var:=string}很常用的一种用法是,判断某个变量是否赋值,没有的话则给它赋上一个默认值。

② ${var:+string}的替换规则和上面的相反,即只有当var不是空的时候才替换成string,若var为空时则不替换或者说是替换成变量 var的值,即空值。(因为变量var此时为空,所以这两种说法是等价的)

      v 
     
    
      a 
     
    
      r 
     
    
      : 
     
    
      ? 
     
    
      s 
     
    
      t 
     
    
      r 
     
    
      i 
     
    
      n 
     
    
      g 
     
    
   
     替换规则为:若变量 
    
   
     v 
    
   
     a 
    
   
     r 
    
   
     不为空,则用变量 
    
   
     v 
    
   
     a 
    
   
     r 
    
   
     的值来替换 
    
   
  
    {var:?string}替换规则为:若变量var不为空,则用变量var的值来替换 
   
  
var:?string替换规则为:若变量var不为空,则用变量var的值来替换{var:?string};若变量var为空,则把string输出到标准错误中,并从脚本中退出。我们可利用此特性来检查是否设置了变量的值。

补充扩展:在上面这五种替换结构中string不一定是常值的,可用另外一个变量的值或是一种命令的输出。

4.5 四种模式匹配替换结构

模式匹配记忆方法:

  • #是去掉左边(在键盘上#在$之左边)
  • %是去掉右边(在键盘上%在$之右边)
  • #和%中的单一符号是最小匹配,两个相同符号是最大匹配。
${var%pattern},${var%%pattern},${var#pattern},${var##pattern}

第一种模式:${variable%pattern},这种模式时,shell在variable中查找,看它是否一给的模式pattern结尾,如果是,就从命令行把variable中的内容去掉右边最短的匹配模式

第二种模式:${variable%%pattern},这种模式时,shell在variable中查找,看它是否一给的模式pattern结尾,如果是,就从命令行把variable中的内容去掉右边最长的匹配模式

第三种模式:${variable#pattern} 这种模式时,shell在variable中查找,看它是否一给的模式pattern开始,如果是,就从命令行把variable中的内容去掉左边最短的匹配模式

第四种模式:${variable##pattern} 这种模式时,shell在variable中查找,看它是否一给的模式pattern结尾,如果是,就从命令行把variable中的内容去掉右边最长的匹配模式

这四种模式中都不会改变variable的值,其中,只有在pattern中使用了匹配符号时,%和%%,#和##才有区别。结构中的pattern支持通配符,表示零个或多个任意字符,?表示仅与一个任意字符匹配,[…]表示匹配中括号里面的字符,[!..]表示不匹配中括号里面的字符。

# var=testcase # echo $var 
testcase 
# echo ${var%s*e} 
testca 
# echo $var 
testcase 
# echo ${var%%s*e} 
te 
# echo ${var#?e} 
stcase 
# echo ${var##?e} 
stcase 
# echo ${var##*e}# echo ${var##*s} 
e 
# echo ${var##test} case

4.6 字符串提取和替换

${var:num},${var:num1:num2},${var/pattern/pattern},${var//pattern/pattern}

第一种模式:

      v 
     
    
      a 
     
    
      r 
     
    
      : 
     
    
      n 
     
    
      u 
     
    
      m 
     
    
   
     ,这种模式时, 
    
   
     s 
    
   
     h 
    
   
     e 
    
   
     l 
    
   
     l 
    
   
     在 
    
   
     v 
    
   
     a 
    
   
     r 
    
   
     中提取第 
    
   
     n 
    
   
     u 
    
   
     m 
    
   
     个字符到末尾的所有字符。若 
    
   
     n 
    
   
     u 
    
   
     m 
    
   
     为正数,从左边 
    
   
     0 
    
   
     处开始;若 
    
   
     n 
    
   
     u 
    
   
     m 
    
   
     为负数,从右边开始提取字串,但必须使用在冒号后面加空格或一个数字或整个 
    
   
     n 
    
   
     u 
    
   
     m 
    
   
     加上括号,如 
    
   
  
    {var:num},这种模式时,shell在 var中提取第num个字符到末尾的所有字符。若num为正数,从左边0处开始;若num为负数,从右边开始提取字串,但必须使用在冒号后面加空格或一个数字或整个num加上括号,如 
   
  
var:num,这种模式时,shell在var中提取第num个字符到末尾的所有字符。若num为正数,从左边0处开始;若num为负数,从右边开始提取字串,但必须使用在冒号后面加空格或一个数字或整个num加上括号,如{var: -2}、 
 
  
   
    
    
      v 
     
    
      a 
     
    
      r 
     
    
      : 
     
    
      1 
     
    
      − 
     
    
      3 
     
    
   
     或 
    
   
  
    {var:1-3}或 
   
  
var:1−3或{var:(-2)}。

第二种模式:

      v 
     
    
      a 
     
    
      r 
     
    
      : 
     
    
      n 
     
    
      u 
     
    
      m 
     
    
      1 
     
    
      : 
     
    
      n 
     
    
      u 
     
    
      m 
     
    
      2 
     
    
   
     , 
    
   
     n 
    
   
     u 
    
   
     m 
    
   
     1 
    
   
     是位置, 
    
   
     n 
    
   
     u 
    
   
     m 
    
   
     2 
    
   
     是长度。表示从 
    
   
  
    {var:num1:num2},num1是位置,num2是长度。表示从 
   
  
var:num1:num2,num1是位置,num2是长度。表示从var字符串的第 
 
  
   
   
     n 
    
   
     u 
    
   
     m 
    
   
     1 
    
   
     个位置开始提取长度为 
    
   
  
    num1个位置开始提取长度为 
   
  
num1个位置开始提取长度为num2的子串。不能为负数。

第三种模式:${var/pattern/pattern}表示将var字符串的第一个匹配的pattern替换为另一个pattern。

第四种模式:${var//pattern/pattern}表示将var字符串中的所有能匹配的pattern替换为另一个pattern。

[root@centos ~]# var=/home/centos [root@centos ~]# echo $var 
/home/centos
[root@centos ~]# echo ${var:5} 
/centos
[root@centos ~]# echo ${var: -6} 
centos 
[root@centos ~]# echo ${var:(-6)} 
centos 
[root@centos ~]# echo ${var:1:4} 
home 
[root@centos ~]# echo ${var/o/h} 
/hhme/centos
[root@centos ~]# echo ${var//o/h} 
/hhme/cenths

参考

shell 中 ()、(())、[]、[[]]、{} 的作用
总结shell 中各种括号的用法 () (())、[]、[[]]、{}
Shell (()):对整数进行数学运算

标签: linux shell 整数

本文转载自: https://blog.csdn.net/m0_45406092/article/details/129045392
版权归原作者 云川之下 所有, 如有侵权,请联系我们删除。

“【Linux】总结shell 中各种括号的用法 () (())、[]、[[]]、{}”的评论:

还没有评论