linux expr命令
Linux expr命令用于在命令行中进行表达式求值,支持整数运算、字符串操作、逻辑运算和模式匹配。
提示: expr命令是Shell脚本编程中常用的工具,虽然现在有更多现代替代品(如$(( ))算术扩展),但在兼容性要求高的场景中仍然很有用。
语法格式
expr 表达式
expr [选项] 表达式
操作符和表达式
| 类别 |
操作符 |
说明 |
示例 |
| 算术运算 |
+ |
加法 |
expr 10 + 20 |
- |
减法 |
expr 30 - 15 |
\* |
乘法(需要转义) |
expr 5 \* 6 |
/ |
整数除法 |
expr 20 / 4 |
|
% |
取模(求余) |
expr 17 % 5 |
| 字符串操作 |
: |
字符串匹配 |
expr "abcde" : "ab" |
length |
字符串长度 |
expr length "hello" |
substr |
子字符串提取 |
expr substr "hello" 2 3 |
index |
字符位置查找 |
expr index "hello" "e" |
| 逻辑运算 |
& |
AND运算 |
expr 1 \& 1 |
| |
OR运算 |
expr 0 \| 1 |
=, >, <, !=, >=, <= |
关系比较 |
expr 5 \> 3 |
使用示例
示例1:基本算术运算
# 加法
expr 10 + 20
# 输出:30
# 减法
expr 50 - 25
# 输出:25
# 乘法(注意*需要转义)
expr 6 \* 7
# 输出:42
# 除法(整数除法)
expr 20 / 4
# 输出:5
# 取模
expr 17 % 5
# 输出:2
示例2:字符串长度和匹配
# 获取字符串长度
expr length "hello world"
# 输出:11
# 获取子字符串
expr substr "hello world" 2 5
# 输出:ello
# 查找字符位置
expr index "hello" "e"
# 输出:2
# 字符串匹配(返回匹配的字符数)
expr "hello world" : "hello"
# 输出:5
expr "hello world" : ".*"
# 输出:11(匹配整个字符串)
示例3:逻辑运算
# 关系比较
expr 5 \> 3
# 输出:1(true)
expr 5 \< 3
# 输出:0(false)
expr 5 = 5
# 输出:1
expr 5 != 5
# 输出:0
# AND运算(两者都为真返回1,否则返回第一个操作数)
expr 1 \& 1
# 输出:1
expr 0 \& 1
# 输出:0
# OR运算(第一个为真返回第一个操作数,否则返回第二个操作数)
expr 0 \| 1
# 输出:1
expr 1 \| 0
# 输出:1
示例4:在Shell脚本中使用
#!/bin/bash
# 计算两个数的和
num1=10
num2=20
sum=$(expr $num1 + $num2)
echo "和为: $sum"
# 检查字符串是否以特定前缀开头
str="hello world"
if [ $(expr "$str" : "hello") -gt 0 ]; then
echo "字符串以'hello'开头"
fi
# 递增计数器
count=0
count=$(expr $count + 1)
echo "当前计数: $count"
示例5:字符串处理
# 提取文件名(不带路径)
fullpath="/home/user/document.txt"
filename=$(expr "$fullpath" : '.*/\(.*\)')
echo "文件名: $filename"
# 提取文件扩展名
filename="document.txt"
extension=$(expr "$filename" : '.*\.\(.*\)')
echo "扩展名: $extension"
# 检查字符串是否包含特定字符
str="hello world"
if [ $(expr index "$str" "o") -gt 0 ]; then
echo "字符串包含字符'o'"
fi
示例6:实际应用场景
# 计算目录中文件数量
file_count=$(expr $(ls -1 | wc -l) - 1) # 减1排除可能的"total"行
echo "文件数量: $file_count"
# 生成序列号(结合seq命令的替代方案)
for i in $(seq 1 5); do
value=$(expr $i \* 10)
echo "编号$i: $value"
done
# 检查参数是否有效
if [ $(expr "$1" : "[0-9]*$") -gt 0 ]; then
echo "参数是数字"
else
echo "参数不是数字"
fi
# 字符串反转(需要复杂处理)
str="hello"
len=$(expr length "$str")
result=""
for i in $(seq $len -1 1); do
char=$(expr substr "$str" $i 1)
result="${result}${char}"
done
echo "反转后: $result"
示例7:与现代Shell算术比较
# 传统expr方式
result=$(expr 10 + 20)
# 现代$(( ))方式
result=$((10 + 20))
# 现代let命令
let "result=10+20"
# 现代(( ))命令
((result=10+20))
# 所有方式都得到相同的结果: 30
注意:
- 操作符与操作数之间必须有空格:
expr 1 + 1 而不是 expr 1+1
- 乘号(*)、大于(>)、小于(<)、与(&)、或(|)等操作符需要转义或加引号
- expr只支持整数运算,不支持浮点数
- 除法是整数除法,结果会向下取整
- expr在比较字符串时,如果比较成功返回1,失败返回0
- expr在比较数字时,需要转义比较操作符
- 在现代bash中,建议使用$(( ))进行算术运算,效率更高
expr与现代Shell算术对比
| 特性 |
expr |
$(( )) |
let |
| 整数运算 |
支持 |
支持 |
支持 |
| 浮点数运算 |
不支持 |
不支持 |
不支持 |
| 字符串操作 |
支持 |
不支持 |
不支持 |
| 模式匹配 |
支持 |
不支持 |
不支持 |
| 性能 |
较慢(外部命令) |
快(内置) |
快(内置) |
| 可移植性 |
高(POSIX标准) |
bash特有 |
bash特有 |
| 语法复杂性 |
较高(需要转义) |
低 |
中等 |
常见错误和解决方案
- 错误:
expr: syntax error
- 原因: 操作符没有转义或缺少空格
- 解决: 为*、>、<等操作符添加转义字符
- 错误:
expr: non-integer argument
- 原因: 使用了非整数参数
- 解决: 确保参数都是整数
性能优化技巧
- 对于简单的整数运算,使用$(( ))替代expr
- 在循环中避免多次调用expr,改用内置算术
- 将多个expr操作合并为一个
- 对于字符串操作,expr可能比sed/awk更高效
- 使用命令替换时注意性能开销
- 考虑使用awk进行复杂的数值计算
相关命令
let - bash内置算术运算命令
bc - 任意精度计算器,支持浮点数
awk - 强大的文本处理工具,支持数学运算
test - 条件测试命令
[ ] - test命令的别名
sed - 流编辑器,支持字符串操作