Linux常用命令学习笔记:expr

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. 注意事项

  1. 空格要求:运算符前后必须有空格
  2. 特殊字符转义*()<>&|等需要转义
  3. 返回值:成功返回0,失败返回非0,计算结果输出到标准输出
  4. 数值范围:支持整数运算,不支持浮点数
  5. 字符串长度:字符串长度不能超过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是表达式求值工具,支持算术运算、字符串操作、逻辑运算
  • 常用操作+-\*/%lengthindexsubstrmatch
  • 实际应用:数值计算、字符串处理、条件判断、文件操作
  • 注意事项:运算符前后必须有空格,特殊字符需要转义,不支持浮点数
  • 返回值:成功返回0,计算结果输出到标准输出

expr命令是Shell脚本中常用的表达式求值工具,熟练掌握可以大大提高脚本编写效率。


作 者:南烛
链 接:https://www.itnotes.top/archives/415
来 源:IT笔记
文章版权归作者所有,转载请注明出处!


上一篇
下一篇