在Linux世界中,expr命令是一个强大的工具,它可以进行数值和字符串的运算操作。无论你是系统管理员还是脚本编写者,掌握expr命令都能让你的工作更加高效。今天,我们就来深入了解一下expr命令的奥秘。
一、命令简介
expr,全称为expression,在Linux系统中作为一款基础的表达式计算工具,主要用于进行整数的算术运算、字符串长度计算以及进行简单的字符串比较等操作。尽管在现代Shell脚本编写中,许多功能已被更为高级的构造如$(( ))或let命令所替代,但expr命令因其兼容性和便利性,仍广泛应用于各种Shell脚本场景。
二、命令用法
expr命令的基本语法如下:
expr Expression
其中,表达式Expression可以是一个算术表达式、比较表达式或字符串表达式。expr命令会对表达式进行求值,并输出结果。
Expression应遵循以下规则:
- 用空格隔开每个项。
- 用\(反斜线)对Shell特殊字符进行转义。
- 对包含空格和其它特殊字符的字符串要用引号括起来。
所有命令都可以放在一对反引号“中,或者是使用命令替换$(),以获取expr的结果并赋值给变量,从而进行其它处理。例如,计算两个整数之和,可以这样使用:
result=$(expr 5 + 2)
result=$(expr $result + 1)
三、日常使用示例
1、数值运算
expr命令支持基本的算术运算,包括加法、减法、乘法、除法和取模。例如:
$ expr 5 + 3 # 输出:8
$ expr 5 \* 3 # 输出:15
$ expr 5 % 3 # 输出:2
注意:乘法操作符(*)需要进行转义,否则会被解释为通配符。
2、比较操作
expr命令还支持比较操作,用于比较两个数值或字符串的大小。例如:
$ expr 5 \>= 5 # 输出:1(表示真)
$ expr 5 \< 5 # 输出:0(表示假)
$ expr foo \> bar # 输出:1(表示真)
$ expr hello != world # 输出:1(表示真)
$ expr hello = hello # 输出:1(表示真)
注意:比较操作符中的大于(>)、小于(<)需要进行转义,否则会被解释为Shell的重定向操作符。
3、字符串操作
expr命令还可以进行字符串操作,如长度计算、子串匹配等。例如:
$ expr length hello # 输出:5(字符串长度)
$ expr index hello e # 输出:2(子串在字符串中的位置)
$ expr substr hello 2 3 # 输出:ell(从第2个字符开始取3个字符的子串)
$ expr abc123 : "[a-z]*[0-9]*" # 输出:6(模式匹配到的文本长度)
$ expr abc123 : "[a-z]*\([0-9]*\)" # 输出:123(捕获模式匹配到的文本)
# expr ARG1 : AGR2 也可以写成 expr match ARG1 AGR2
注意:这里的正则表达式并未完全按照POSIX扩展正则标准,expr中的正则表达式功能相对有限。使用圆括号用于捕获文本,需要对圆括号进行转义(\(..\)),如果有多组括号,只会输出第一个捕获组的内容。
在Bash脚本编写中,我们更倾向于使用grep、sed或者Shell的内建 ${#variable}、${variable:offset:length}、${variable#prefix} 和 ${variable%suffix} 等方式进行字符串操作,因为它们的功能更为强大且易于使用。但对于一些旧版系统或特定场景下,expr仍然是一个可用的选择。
4、逻辑运算
expr命令还可以进行逻辑操作:
$ expr ARG1 \| ARG2 # 若ARG1的值不为null或0,则返回ARG1,否则返回ARG2
$ expr 0 \| 5 # 输出:5
$ expr ARG1 \& ARG2 # 若两边的值都不为null或0,则返回ARG1,否则返回0
$ expr 2 \& 5 # 输出:2
注意:或操作符(|)、与操作符(&)需要进行转义。否则,前者会被解释为Shell的管道符,后者会被解释为命令分隔符,它前面的部分作为一个命令将在后台运行,后面的部分作为另一个命令运行。
需要注意的是,expr命令中运算符两边的操作数如果包含空格或者可能是空字符串,空格前必须加上转义字符(\),或者将操作数放在引号中。这是因为空格在Shell中有特殊意义(被当成参数分隔符),而空字符串通常不会被Shell传递给命令,在这种情况下命令会显示错误信息:expr: syntax error。这一点适用很多场景,但在Bash中使用双中括号([[ ]])时,不用考虑这些情况。例如,以下两种方式都可以比较两个变量是否相等:
expr "$a" = "$b"
[[ $a = $b ]]
当其中一个或两个参数为空、或者包含空格时,命令都能正确执行。
四、为什么要使用expr
相对于Bash等Shell中的高级用法,expr有其独特的兼容性和便利性。例如,要计算一段文本的长度,常规做法:
$ var='This is a paragraph of text'
$ echo ${#var}
# 输出:27
或者:
$ printf 'This is a paragraph of text'|wc -c
# 输出:27
使用expr直接计算这段文本的长度:
$ expr length 'This is a paragraph of text'
# 输出:27
再看另一个使用场景,在函数中返回计算结果,以计算两个时间之间相差的秒数为例(时间格式为:yyyy-mm-dd HH:MM:SS):
function time_diff() {
local t1=$(date -d "$1" +%s)
local t2=$(date -d "$2" +%s)
diff=$[t1-t2]
echo $diff
}
如果使用expr,函数可以写成这样:
function time_diff() {
local t1=$(date -d "$1" +%s)
local t2=$(date -d "$2" +%s)
expr $t1 - $t2
}
这样看起来更直观。
总结
理解并熟练运用expr命令,将让你的Linux命令行操作更加得心应手,也会提升数据处理和脚本编程的能力。