1. 命令概述
- 命令名称:
expr(英文全拼:expression) - 核心功能:表达式求值,对字符串和数值进行运算
- 主要用途:数值计算、字符串操作、逻辑运算
- 特点:支持基本算术运算、字符串匹配、逻辑比较
2. 语法格式
expr 表达式
3. 基本操作
(1) 算术运算
# 加法
expr 10 + 20
# 减法
expr 30 - 15
# 乘法(需要转义*)
expr 5 \* 4
# 除法
expr 20 / 5
# 取余
expr 20 % 3
# 括号运算
expr \( 10 + 20 \) \* 2
(2) 字符串操作
# 字符串长度
expr length "hello"
# 子字符串位置
expr index "hello" "e"
# 提取子字符串
expr substr "hello" 2 3
# 字符串匹配
expr match "hello" "h.*o"
# 正则表达式匹配
expr "hello" : "h.*o"
(3) 逻辑运算
# 等于
expr 10 = 10
# 不等于
expr 10 != 20
# 大于
expr 20 \> 10
# 小于
expr 10 \< 20
# 大于等于
expr 20 \>= 10
# 小于等于
expr 10 \<= 20
# 与运算
expr 1 \& 1
# 或运算
expr 0 \| 1
4. 常用实例详解
(1) 数值计算
# 计算两个数的和
a=10
b=20
sum=$(expr $a + $b)
echo $sum # 输出:30
# 计算两个数的乘积
product=$(expr $a \* $b)
echo $product # 输出:200
# 计算两个数的商
quotient=$(expr $b / $a)
echo $quotient # 输出:2
# 计算余数
remainder=$(expr $b % $a)
echo $remainder # 输出:0
# 复杂表达式
result=$(expr \( $a + $b \) \* 2 )
echo $result # 输出:60
(2) 字符串处理
# 获取字符串长度
str="hello world"
len=$(expr length "$str")
echo $len # 输出:11
# 查找字符位置
pos=$(expr index "$str" "w")
echo $pos # 输出:7
# 提取子字符串
sub=$(expr substr "$str" 7 5)
echo $sub # 输出:world
# 正则匹配
match=$(expr "$str" : "hello.*")
echo $match # 输出:11
# 匹配并提取
extract=$(expr "$str" : 'hello \(.*\)')
echo $extract # 输出:world
(3) 逻辑判断
# 判断两个数是否相等
if [ $(expr 10 = 10) -eq 1 ]; then
echo "相等"
else
echo "不相等"
fi
# 判断两个数的大小
if [ $(expr 20 \> 10) -eq 1 ]; then
echo "20大于10"
else
echo "20不大于10"
fi
# 判断字符串是否为空
str=""
if [ $(expr length "$str") -eq 0 ]; then
echo "字符串为空"
else
echo "字符串不为空"
fi
# 判断文件是否存在
file="test.txt"
if [ $(expr length "$file") -gt 0 ] && [ -f "$file" ]; then
echo "文件存在"
else
echo "文件不存在"
fi
(4) 条件判断
# 判断数字范围
num=15
if [ $(expr $num \>= 10) -eq 1 ] && [ $(expr $num \<= 20) -eq 1 ]; then
echo "数字在10到20之间"
else
echo "数字不在10到20之间"
fi
# 判断字符串是否以指定字符开头
str="hello world"
if [ $(expr "$str" : "hello.*") -gt 0 ]; then
echo "字符串以hello开头"
else
echo "字符串不以hello开头"
fi
# 判断字符串是否包含指定字符
if [ $(expr index "$str" "world") -gt 0 ]; then
echo "字符串包含world"
else
echo "字符串不包含world"
fi
5. 实际应用场景
场景一:数值计算
# 计算文件行数
lines=$(wc -l file.txt | awk '{print $1}')
echo "文件有 $lines 行"
# 计算文件大小(KB)
size=$(expr $(wc -c file.txt | awk '{print $1}') / 1024)
echo "文件大小为 $size KB"
# 计算平均值
sum=0
count=0
while read num; do
sum=$(expr $sum + $num)
count=$(expr $count + 1)
done < numbers.txt
average=$(expr $sum / $count)
echo "平均值为 $average"
# 计算阶乘
factorial=1
for i in $(seq 1 5); do
factorial=$(expr $factorial \* $i)
done
echo "5的阶乘是 $factorial"
场景二:字符串处理
# 提取文件名(不含扩展名)
filename="document.txt"
name=$(expr "$filename" : '\(.*\)\.')
echo $name # 输出:document
# 提取文件扩展名
extension=$(expr "$filename" : '.*\.\(.*\)')
echo $extension # 输出:txt
# 提取URL中的域名
url="https://www.example.com/path"
domain=$(expr "$url" : 'https://\([^/]*\)')
echo $domain # 输出:www.example.com
# 提取IP地址的各个部分
ip="192.168.1.100"
part1=$(expr "$ip" : '\([0-9]*\)')
part2=$(expr "$ip" : '[0-9]*\.\([0-9]*\)')
part3=$(expr "$ip" : '[0-9]*\.[0-9]*\.\([0-9]*\)')
part4=$(expr "$ip" : '[0-9]*\.[0-9]*\.[0-9]*\.\([0-9]*\)')
echo "IP地址:$part1.$part2.$part3.$part4"
# 判断字符串是否为数字
str="12345"
if [ $(expr "$str" : '[0-9]*$') -eq $(expr length "$str") ]; then
echo "是数字"
else
echo "不是数字"
fi
场景三:条件判断
# 判断数字是否为偶数
num=10
if [ $(expr $num % 2) -eq 0 ]; then
echo "偶数"
else
echo "奇数"
fi
# 判断年份是否为闰年
year=2024
if [ $(expr $year % 4) -eq 0 ] && [ $(expr $year % 100) -ne 0 ] || [ $(expr $year % 400) -eq 0 ]; then
echo "$year 是闰年"
else
echo "$year 不是闰年"
fi
# 判断字符串是否为空或只包含空格
str=" "
if [ $(expr length "$str") -eq 0 ]; then
echo "字符串为空"
else
echo "字符串不为空"
fi
# 判断文件是否可读
file="test.txt"
if [ $(expr length "$file") -gt 0 ] && [ -r "$file" ]; then
echo "文件可读"
else
echo "文件不可读"
fi
6. 与其他命令的区别
| 命令 | 特点 | 适用场景 |
|---|---|---|
expr | 表达式求值,支持算术和字符串运算 | 数值计算、字符串操作 |
let | 算术运算,更简洁 | 简单的算术运算 |
bc | 高精度计算器 | 复杂数学运算 |
awk | 文本处理工具,支持字段运算 | 复杂文本处理 |
test | 条件测试 | 条件判断 |
7. 注意事项
- 空格要求:运算符前后必须有空格
- 特殊字符转义:
*、(、)、<、>、&、|等需要转义 - 返回值:成功返回0,失败返回非0,计算结果输出到标准输出
- 数值范围:支持整数运算,不支持浮点数
- 字符串长度:字符串长度不能超过255个字符
8. 常见问题解决
(1) 特殊字符转义
# 乘法需要转义*
expr 5 \* 4
# 括号需要转义
expr \( 10 + 20 \) \* 2
# 大于小于需要转义
expr 20 \> 10
expr 10 \< 20
# 与或运算需要转义
expr 1 \& 1
expr 0 \| 1
(2) 空格问题
# 错误:缺少空格
expr 10+20 # 输出:10+20
# 正确:运算符前后有空格
expr 10 + 20 # 输出:30
# 错误:变量引用缺少引号
a=10
b=20
expr $a+$b # 输出:10+20
# 正确:变量引用加引号
expr "$a" + "$b" # 输出:30
(3) 浮点数处理
# expr不支持浮点数
expr 10 / 3 # 输出:3
# 使用bc处理浮点数
echo "scale=2; 10 / 3" | bc # 输出:3.33
# 使用awk处理浮点数
awk 'BEGIN{print 10/3}' # 输出:3.33333
(4) 大数处理
# expr支持整数范围有限
expr 1000000000 \* 1000000000 # 可能溢出
# 使用bc处理大数
echo "1000000000 * 1000000000" | bc # 输出:1000000000000000000
# 使用awk处理大数
awk 'BEGIN{print 1000000000 * 1000000000}' # 输出:1e+18
核心要点总结:
expr是表达式求值工具,支持算术运算、字符串操作、逻辑运算- 常用操作:
+、-、\*、/、%、length、index、substr、match - 实际应用:数值计算、字符串处理、条件判断、文件操作
- 注意事项:运算符前后必须有空格,特殊字符需要转义,不支持浮点数
- 返回值:成功返回0,计算结果输出到标准输出
expr命令是Shell脚本中常用的表达式求值工具,熟练掌握可以大大提高脚本编写效率。