expr命令全解
expr(expression 的缩写)是 Linux/Unix 系统中一款经典的命令行工具,主要用于整数运算、字符串处理和逻辑判断。它通过命令行参数接收表达式,计算并输出结果,常被用于 shell 脚本中处理简单的数值和字符串操作。本文将从基础语法到高级用法,全面解析 expr 命令的功能与实践。
一、expr 基本语法与特性
1. 语法格式
expr 的核心语法非常简单,通过空格分隔表达式的各个元素:
expr 表达式
其中,“表达式” 可以是整数运算(如
1 + 2
)、字符串操作(如 length "hello"
)或逻辑判断(如 5 > 3
)。2. 核心特性
- 无交互模式:所有操作通过命令行参数完成,无交互式输入;
- 返回值规则:
- 计算成功时,输出表达式结果(整数或字符串);
- 计算失败时(如语法错误、运算不成立),输出空值,且返回状态码非 0(可通过
$?
查看);
- 适用场景:shell 脚本中处理简单运算、字符串长度计算、模式匹配等轻量任务。
二、整数运算:最常用的核心功能
expr 支持基本的整数算术运算,包括加、减、乘、除、取余,运算符号前后必须有空格(否则会被视为字符串)。
1. 加法(+)
expr 10 + 5 # 输出:15
expr 2 + -3 # 支持负数,输出:-1
2. 减法(-)
expr 10 - 5 # 输出:5
expr 5 - 10 # 输出:-5
3. 乘法(*)
注意:
*
在 shell 中是通配符,必须用反斜杠 \
转义:expr 10 \* 5 # 输出:50
expr 3 \* -2 # 输出:-6
4. 除法(/)
仅支持整数除法,结果向下取整(截断小数部分):
expr 10 / 3 # 输出:3(10÷3=3.333,截断为3)
expr 7 / 2 # 输出:3
expr -10 / 3 # 输出:-3(向下取整)
5. 取余(%)
返回除法的余数(结果符号与被除数一致):
expr 10 % 3 # 输出:1(10 = 3×3 + 1)
expr 7 % 2 # 输出:1
expr -10 % 3 # 输出:-1(-10 = 3×(-4) + (-1))
三、字符串操作:处理文本的实用功能
expr 提供了简单的字符串处理能力,包括计算长度、查找字符位置、模式匹配等,适合轻量文本处理场景。
1. 计算字符串长度(length)
expr length "hello" # 输出:5("hello"有5个字符)
expr length "hello world" # 输出:11(包含空格)
2. 查找字符在字符串中首次出现的位置(index)
expr index "字符串" "字符集"
:返回 “字符集” 中任意字符在 “字符串” 中首次出现的位置(从 1 开始计数,无匹配则返回 0)。expr index "hello" "l" # 输出:3("l"在"hello"中首次出现在第3位)
expr index "hello" "aeiou" # 输出:2(元音字母"e"在第2位)
expr index "hello" "xyz" # 输出:0(无匹配字符)
注意:
index
匹配的是 “字符集中的任意单个字符”,而非字符串整体。3. 字符串模式匹配(match 或 :)
用于判断字符串是否匹配指定模式(支持基础正则表达式),返回匹配的长度(无匹配则返回 0)。两种语法等价:
expr match "字符串" "模式"
expr "字符串" : "模式"
常用示例:
# 匹配以"he"开头的字符串,返回匹配长度
expr match "hello" "he" # 输出:2
expr "hello" : "he" # 输出:2
# 匹配数字开头的字符串(正则 \([0-9]\+\) 捕获数字)
expr "123abc" : "\([0-9]\+\)" # 输出:3(匹配"123",长度3)
expr "abc123" : "\([0-9]\+\)" # 输出:0(非数字开头,无匹配)
# 匹配任意字符(. 表示任意单字符,* 表示前面字符出现0次或多次)
expr "test.txt" : "test.*" # 输出:8("test.txt"整体匹配,长度8)
说明:模式中的
\(` 和 `\)
用于捕获匹配的子串(仅返回捕获部分的长度),无捕获时返回整个匹配的长度。4. 提取子字符串(substr)
expr substr "字符串" 起始位置 长度
:从 “起始位置”(从 1 开始)提取指定 “长度” 的子串。expr substr "hello world" 1 5 # 输出:hello(从第1位开始,取5个字符)
expr substr "hello world" 7 5 # 输出:world(从第7位开始,取5个字符)
expr substr "hello" 3 2 # 输出:ll(从第3位开始,取2个字符)
四、逻辑判断:比较与条件验证
expr 可进行整数或字符串的比较运算,返回1(真) 或0(假),常与 shell 条件语句(如
if
)结合使用。1. 整数比较
运算符 | 含义 | 示例(返回 1 为真,0 为假) |
---|---|---|
= |
等于 | expr 5 = 5 → 1;expr 5 = 3 → 0 |
!= |
不等于 | expr 5 != 3 → 1;expr 5 !=5 →0 |
> |
大于 | expr 5 > 3 → 1;expr 3 >5 →0 |
< |
小于 | expr 3 < 5 → 1;expr 5 <3 →0 |
>= |
大于等于 | expr 5 >=5 →1;expr 3 >=5 →0 |
<= |
小于等于 | expr 3 <=5 →1;expr 5 <=3 →0 |
注意:
<
和 >
在 shell 中是重定向符号,必须用反斜杠 \
转义:expr 5 \> 3 # 输出:1(5>3为真)
expr 3 \< 5 # 输出:1(3<5为真)
2. 字符串比较
字符串比较仅支持
=
(等于)和 !=
(不等于),按字符 ASCII 码逐位比较:expr "abc" = "abc" # 输出:1(相等)
expr "abc" = "abd" # 输出:0(不相等)
expr "abc" != "def" # 输出:1(不相等)
3. 在 shell 脚本中结合条件判断
#!/bin/bash
a=10
b=5
# 判断 a 是否大于 b
if [ $(expr $a \> $b) -eq 1 ]; then
echo "$a 大于 $b"
else
echo "$a 不大于 $b"
fi
# 输出:10 大于 5
五、实战场景:expr 命令的典型用法
1. 脚本中简单的数值计算
#!/bin/bash
# 计算两个数的和、差、积、商
read -p "输入第一个数:" num1
read -p "输入第二个数:" num2
sum=$(expr $num1 + $num2)
diff=$(expr $num1 - $num2)
prod=$(expr $num1 \* $num2)
quotient=$(expr $num1 / $num2)
echo "和:$sum"
echo "差:$diff"
echo "积:$prod"
echo "商:$quotient"
2. 验证输入是否为纯数字
利用模式匹配判断字符串是否全为数字:
#!/bin/bash
read -p "请输入一个数字:" input
# 匹配纯数字(^ 表示开头,$ 表示结尾,[0-9]\+ 表示1个以上数字)
if [ $(expr "$input" : "^[0-9]\+$") -gt 0 ]; then
echo "输入是纯数字"
else
echo "输入不是纯数字"
fi
3. 提取文件名与扩展名
#!/bin/bash
file="document.txt"
# 提取文件名(不包含扩展名)
filename=$(expr "$file" : "\(.*\)\.")
# 提取扩展名
extension=$(expr "$file" : ".*\(\..*\)")
echo "文件名:$filename" # 输出:document
echo "扩展名:$extension" # 输出:.txt
六、注意事项与局限性
1. 必须注意的语法细节
- 运算符前后必须有空格:
expr 1+2
会被视为字符串 “1+2”,返回错误;正确写法是expr 1 + 2
。 - 特殊字符需转义:
*
、(
、)
、<
、>
等在 shell 中有特殊含义,必须用\
转义(如\*
、\<
)。 - 字符串含空格需加引号:如
expr length "hello world"
,不加引号会被解析为多个参数,导致错误。
2. 局限性
- 不支持浮点数运算:expr 仅能处理整数,浮点数计算需用
bc
或awk
(如echo "2.5 + 3.5" | bc
)。 - 正则表达式支持有限:仅支持基础正则(如
*
、+
、[]
),不支持扩展正则(如?
、()
分组)。 - 性能较低:复杂运算或大量数据处理时,效率远低于
awk
或 Python 脚本。