expr命令可以实现数值运算、数值或字符串比较、字符串匹配、字符串提取、字符串长度计算等功能。它还具有几个特殊功能,判断变量或参数是否为整数、是否为空、是否为0等。
注意:
(1) 所有操作符的两边,都需要有空格。
错误:
[root@localhost scripts]# expr 1+1
1+1
[root@localhost scripts]# expr (1+1)
-bash: 未预期的符号 `1+1' 附近有语法错误
正确:
[root@localhost scripts]# expr 1 + 1
2
(2) 数值表达式("+ - * / %")和比较表达式("< <= = == != >= >")会先将两端的参数转换为数值,转换失败将报错。所以可借此来判断参数或变量是否为整数。
(3) expr中的很多符号需要转义或使用引号包围。
expr示例:
1、"string : REGEX"字符串匹配示例。要输出匹配到的字符串结果,需要使用"\("和"\)",否则返回的将是匹配到的字符串数量。
[root@localhost ~]#expr abcde : 'ab\(.*\)' # 'ab\(.*\)' ab代表不匹配 .代表匹配一个 .*匹配所有 \是为了转移字符,转移( 和)
cde
[root@localhost ~]# expr abcde : 'ab\(.\)'
c
[root@localhost ~]# expr abcde : 'ab\(..\)'
cd
[root@localhost ~]# expr abcde : 'ab.*' # 不写() 代表反馈匹配上的数字各个数
5
[root@localhost ~]# expr abcde : 'ab.'
3
[root@localhost ~]# expr abcde : '.*cd*'
4
[root@localhost ~]# cat abc
abcdwe
[root@localhost ~]# expr `cat abc` : 'ab\(..\)'
cd
注意: 由于REGEX中隐含了"^",所以使得匹配时都是从string首字符开始的。
[root@localhost ~]# expr abcde : 'cd\(.*\)'
[root@localhost ~]# expr abcde : 'cd.*'
0
2、"index string chars"用法示例。
该表达式是从string中搜索chars中某个字符的位置,这个字符是string中最靠前的字符。例如:
[root@localhost ~]# expr index abcde dec # 在 abcde 中搜索 d 在第几个位置
3
该命令将对字符串"dec"逐字符分解,首先分解得到第一个字符d,从abcde中搜索到d的位置为4,再分解得到第二个字符e,该字符在abcde中的位置为5,最后得到的字符是c,该字符在abcde中的位置为3。其中3是最靠前的字符,所以命令返回的结果为3。
[root@localhost ~]# expr index abcde xdc # 在 abcde 中搜索x没有,在搜索d
3
如果chars中的所有字符都不存在于string中,则返回0。
[root@localhost ~]# expr index abcde 1
0
[root@localhost ~]#
3、"substr string pos len"用法示例。
该表达式是从string中取出从pos位置开始长度为len的子字符串。如果pos或len为非正整数时,将返回空字符串。
[root@localhost ~]# expr substr abcde 2 3
bcd
[root@localhost ~]# expr substr abcde 2 4
bcde
[root@localhost ~]# expr substr abcde 2 5
bcde
[root@localhost ~]# expr substr abcde 2 0
[root@localhost ~]# expr substr abcde 2 -1
4."length string"用法示例。该表达式是返回string的长度,其中string不允许为空,否则将报错,所以可以用来判断变量是否为空。
[root@xuexi ~]# expr length abcde
5
[root@xuexi ~]# expr length 111
3
[root@localhost scripts]# echo $xxx
[root@xuexi ~]# expr length $xxx
expr: syntax error
5."+ token"用法示例。
expr中有些符号和关键字有特殊意义,如"match"、"index"、"length",如果要让其成为字符,使用该表达式将任意token强制解析为普通字符串。格式:expr index 特殊关键字
[root@localhost scripts]# expr index index d
expr: 语法错误
[root@localhost scripts]# expr index length g
expr: 语法错误
[root@localhost scripts]# expr index + length g
4
对值为关键字的变量来说,则无所谓。
[root@localhost scripts]# len=lenght
[root@localhost scripts]# expr index $len g
4
6.算术运算用法示例。
[root@localhost scripts]# expr 1 + 2
3
[root@localhost scripts]# a=3
[root@localhost scripts]# b=4
[root@localhost scripts]# expr $a + $b
7
[root@localhost scripts]# expr 4 + $a
7
[root@localhost scripts]# expr $a - $b
-1
算术乘法符号"*"因为是shell的元字符,所以要转义,可以使用引号包围,或者使用反斜线。
乘法:
[root@localhost scripts]# expr $a * $b
expr: 语法错误
[root@localhost scripts]# expr $a \* $b
12
[root@localhost scripts]# expr $a '*' $b
12
除法:
[root@localhost scripts]# expr $a / $b # 除法只能取整数
0
[root@localhost scripts]# expr $a \/ $b
0
取余:
[root@localhost scripts]# expr $a % $b
3
[root@localhost scripts]# expr $a \% $b
3
由于expr在进行算术运算时,首先会将操作符两边的参数转换为整数,任意一端转换失败都将会报错,所以可以用来判断参数或变量是否为整数。
[root@localhost scripts]# expr $a + $c
expr: 语法错误
[root@localhost scripts]# if [ $? != 0 ];then echo '$a or $c is non-integer';fi
$a or $c is non-integer
7.比较操作符< <= = == != >= >用法示例。其中"<"和">"是正则表达式正的锚定元字符,且"<"会被shell解析为重定向符号,所以需要转义或用引号包围。
这些操作符会首先会将两端的参数转换为数值,如果转换成功,则采用数值比较,如果转换失败,则按照字符集的排序规则进行字符大小比较。比较的结果若为true,则expr返回1,否则返回0。
[root@localhost scripts]# a=3
[root@localhost scripts]# expr $a = 1
0
[root@localhost scripts]# expr $a = 3
1
[root@localhost scripts]# expr $a \* 3 = 9
1
一位一位比较
[root@localhost scripts]# expr abc \> ab
1
[root@localhost scripts]# expr akc \> ackd
1
[root@localhost scripts]# expr ack \> akc
0
8.逻辑连接符号"&"和"|"用法示例。这两个符号都需要转义,或使用引号包围。
以下是官方文档中给出的解释,但实际使用过程中是不完全正确的。
"&"表示如果两个参数同时满足非空且非0,则返回第一个参数的值,否则返回0。且如果发现第一个参数为空或0,则直接跳过第二个参数不做任何计算。
"|"表示如果第一个参数非空且非0,则返回第一个参数值,否则返回第二个参数值,但如果第二个参数为空或为0,则返回0。且如果发现第一个参数非空或非0,也将直接跳过第二个参数不做任何计算。
正确的应该是:
"&"表示如果两个参数都非0,则返回第一个参数,否则返回0。但任意一个参数为空,则expr报错。除非空字符串使用引号包围,则处理方法和0一样。
"|"表示如果第一个参数非0,则返回第一个参数的值,否则返回第二个参数。但如果任意一个参数为空,则expr报错。除非空字符串使用引号包围,则处理方法和0一样。
[root@localhost scripts]# expr $abc '|' 1
expr: syntax error
[root@localhost scripts]# expr "$abc" '|' 1
1
[root@localhost scripts]# expr "$abc" '&' 1
0
[root@localhost scripts]# expr $abc '&' 1
expr: syntax error
[root@localhost scripts]# expr 0 '&' abc
0
[root@localhost scripts]# expr abc '&' 0
0
[root@localhost scripts]# expr abc '|' 0
abc
[root@localhost scripts]# expr 0 '|' abc
abc
[root@localhost scripts]# expr abc '&' cde
abc
[root@localhost scripts]# expr abc '|' cde
abc