判断正则 shell_【US分享】Shell中的括号

6bda2ffdddde26f423163ed46b17dd60.png

小U有一天想要使用shell脚本跑一段时间的脚本,写了下面一段shell语句,发现报错了,运行的时候变成了这样:

6ff23dcbe8c5b2b0594ff91ff7bc5113.png

22d7b4dfce7caa2d446eb30e6a923365.png

一开始以为是由于bash将0开头的数字作为8进制了,所以出现08,09这样的数字就会报错,之后发现是由于是用错了关键词和括号导致的。自此小U仿佛打开了新世界的大门,之前并没有系统了解过shell中的括号,经常出现混用的情况,今天我们就来总结一下shell中各种括号的使用方法和场景。

单小括号——( )

1) 命令组:

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

516ed4105e92ba419884fc55a31a5b27.png

2) 初始化数组

其次小括号常被用于初始化数组。下图为初始化数组并对数组进行遍历输出。

8a5dc532be7cb8203ec778f1bf67a534.png

3) 命令替换:

等同于 `cmd` ,shell扫描一遍命令行,发现了$(cmd)结构,便将$(cmd)中的cmd执行一次,得到其标准输出,再将此输出放到原来命令中。

7509f14343ad26bce2f0d56780126947.png

双小括号——(( ))

1) 整数扩展:

这种扩展计算是整数型的计算,不支持浮点型。((exp))结构扩展并计算一个算术表达式的值,如果表达式的结果为0,那么返回的退出状态码为1,或者 是"假",而一个非零值的表达式所返回的退出状态码将为0,或者是"true"。若是逻辑判断,表达式exp为真则为1,假则为0。

2) 进制转化:

只要括号中的运算符、表达式符合C语言运算规则,都可用在$((exp))中,甚至是三目运算符。作不同进位(如二进制、八进制、十六进制)运算时,输出结果全都自动转化成了十进制。

ce0c773b53dbe6774af217d706f52dcd.png

3) 重定义变量值

可以对变量进行重定义,下图对变量a执行了++操作。

a7055dc5aedce43027b040047dda7ec6.png

4) 算术运算比较

双括号中的变量可以不使用$符号前缀。括号内支持多个表达式用逗号分开。只要括号中的表达式符合C语言运算规则,比如可以直接使用for((i=0;i<5;i++)),其他写法包括for i in `seq 0 4` 或者for i in {0..4}。再如可以直接使用if (($i<5)), 如果不使用双括号, 则为if [ $i -lt 5 ]。注意浮点数是作为字符串处理。

单中括号——[ ]

1) 相当于test

“[”和test是等同的,if/test结构中的左中括号是调用test的命令标识,右中括号是关闭条件判断的。这个命令把它的参数作为比较表达式或者作为文件测试(判断文件是否存在是否可执行等),并且根据比较的结果来返回一个退出状态码。

2) 整数和字符串的比较

[ ]中可用的比较运算符只有==和!=,两者都是用于字符串比较的,不可用于整数比较,整数比较只能使用-eq,-gt这种形式。不能直接使用大于小于号。对于字符串比较可以使用转义形式,如果比较"ab"和"bc":[ ab \< bc ],结果为真,也就是返回状态为0。[ ]中的逻辑与和逻辑或使用-a 和-o 表示。

f5a939461b9e9ed0318a26c92b326782.png

83652c19c4c0afc7d921a54f8e3e2096.png

3) 字符范围

使用起来类似用作正则表达式的一部分,描述一个匹配的字符范围。

4) 在数组中括号用来引用数组中每个元素的编号

1a669515641ced8efbe6078f99159c1b.png

注意:$[ expr ]和$(( expr ))是一样的,都是进行数学运算的。支持+ - * / %(“加、减、乘、除、取模”)。但是注意,bash只能作整数运算,对于浮点数是当作字符串处理的。

双中括号——[[ ]]

1)部分shell中的内置命令

这是内置在部分shell中的一个命令,它就比刚才说的test强大的多了。支持字符串的模式匹配(使用=~操作符时甚至支持shell的正则表达式)。逻辑组合可以不使用test的-a,-o而使用&& ||。

2)模式匹配

字符串比较时可以把右边的作为一个模式,而不仅仅是一个字符串,比如[[ hello == hell? ]],结果为真。[[ ]] 中匹配字符串或通配符,不需要引号。

3)防止脚本中的许多逻辑错误

使用[[ ... ]]条件判断结构,而不是[ ... ],能够防止脚本中的许多逻辑错误。比如,&&、||、 操作符能够正常存在于[[ ]]条件判断结构中,但是如果出现在[ ]结构中的话,会报错。比如可以直接使用if [[ $a != 1 && $a != 2 ]], 如果不适用双括号, 则为if [ $a -ne 1] && [ $a != 2 ]或者if [ $a -ne 1 -a $a != 2 ]。

注意:使用[]和[[]]的时候不要吝啬空格,每一项两边都要有空格,[[ 1 == 2 ]]的结果为“假”,但[[ 1==2 ]]的结果为“真”!

大括号——{ }

1)大括号拓展

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

5fb20df58b26f869a3072d99dda3441c.png

2)代码块(又被称为内部组)

这个结构事实上创建了一个匿名函数,与小括号中的命令不同,大括号内的命令不会新开一个子shell运行,即脚本余下部分仍可使用括号内变量。括号内的命令间用分号隔开,最后一个也必须有分号。{ }的第一个命令和左括号之间必须要有一个空格。下图中可以看到小括号括起来的部分只在对应子shell中作用,参数并没有传出来。

b56528b15c25f28a15b96636783b8b06.png

3)字符串提取和替换

类似python中的substr和replace方法。下图测试了几重常用的字符提取替换方法。

30e3f57f3e042e17bbf681a8480d9f32.png

4)模匹配替换结构

  • ${variable}用于变量替换。一般情况下,$var 与${var} 并没有什么不一样,但是用 ${ } 会比较精确的界定变量名称的范围。

  • 假设我们定义了一个变量为:file=/dir1/dir2/dir3/my.file.txt,我们可以用 ${ } 分别替换获得不同的值:

${file*/}:拿掉第一条 / 及其左边的字符串:dir1/dir2/dir3/my.file.txt ${file*/}:拿掉最后一条 / 及其左边的字符串:my.file.txt ${file*.}:拿掉第一个 .  及其左边的字符串:file.txt ${file*.}:拿掉最后一个 .  及其左边的字符串:txt ${file%/*}:拿掉最后条 / 及其右边的字符串:/dir1/dir2/dir3 ${file%%/*}:拿掉第一条 / 及其右边的字符串:(空值) ${file%.*}:拿掉最后一个 .  及其右边的字符串:/dir1/dir2/dir3/my.file ${file%%.*}:拿掉第一个 .  及其右边的字符串:/dir1/dir2/dir3/my

总结

  • (…) 是命令列表。这些命令在单独的子过程中执行,因此在括号内执行的任何重定向,赋值等在括号外均无效。{ … }大括号类似于括号,但是在当前shell中执行,语法有所不同。

  • $(…)是命令的替换:括号内有一个命令,并且命令的输出用作命令行的一部分,等价于反引号。

  • ((…))双括号将算术指令(对整数的计算)括起来,其语法类似于其他编程语言。此语法主要用于赋值和条件句中。

  • $((…))是算术表达式,该语法扩展为表达式计算后的整数值。

  • [ … ]单括号包围条件表达式。条件表达式主要建立在运算符上。不能直接用>

  • [[ … ]]双括号是部分shell中条件表达式的替代形式,具有一些附加功能,在对字符串进行比较判断的时候最好使用这个。

  • 带有前导美元符号的${VAR}是参数扩展,扩展为变量的值,并可能进行额外的转换。

  • 比较的时候慎用shell中的字符串比较,如果要使用的话使用bash中的[[ ]]更符合一般的编程习惯。

  • 如果要使用选的日期,时间等,尽量将其转化为yyyymmdd形式或者秒数,通过整数的比较和计算之后再转回需要的形式,这样可以减少错误的发生。

往期推荐:

【UI分享】游戏交互提升技巧,想看吗?

【RD分享】正确处理CSRF校验

【UE分享】玩家吐槽“猪队友”时,到底在吐槽什么?

【UI分享】远程武器准星设计方法论

【US分享】如何实现shell脚本的单例运行

ddb13360b0f831e9d95338efa17d7194.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值