Linux `expr` 命令详解

Linux expr 命令详解


🎯 学习目标

  1. 掌握 expr 命令的基本语法和常用功能
  2. 理解 expr 在 Shell 脚本中进行数学运算、字符串匹配、逻辑判断的使用方法
  3. 能够在实际脚本开发中灵活运用 expr 解决问题(如路径提取、条件判断)
  4. 了解 expr 与现代 Bash 运算符之间的差异及替代方案

🔑 核心重点

功能 说明
数值运算 支持加减乘除取模等基本运算
字符串处理 提取子串、匹配正则表达式
逻辑判断 比较大小、是否为整数等
返回值机制 成功返回结果,失败返回非零值
使用限制 表达式中需空格分隔操作符
实际应用场景 Shell 脚本中的动态计算、文本处理、流程控制

🧠 详细讲解

📌 一、什么是 expr

expr 是一个 古老的 Unix 工具,用于在命令行或 Shell 脚本中执行 表达式求值。它可以处理:

  • 整数运算(+ - * / %)
  • 字符串操作(截取、匹配)
  • 条件判断(比较大小)

📌 基本语法

expr 表达式

⚠️ 注意:expr 对格式要求严格,操作符必须用空格隔开!


📌 二、基础用法示例

✅ 示例 1:数值运算

$ expr 5 + 3
8

$ expr 10 - 4
6

$ expr 7 \* 3
21

📌 注意:乘号 * 需要转义!


✅ 示例 2:变量运算

a=10
b=5
result=$(expr $a + $b)
echo "结果是: $result"

输出:

结果是: 15

✅ 示例 3:字符串长度

str="hello world"
len=$(expr length "$str")
echo "字符串长度: $len"

输出:

字符串长度: 11

✅ 示例 4:字符串截取

str="abcdefg"
sub=$(expr substr "$str" 2 3)
echo "从第2个字符开始取3个字符: $sub"

输出:

从第2个字符开始取3个字符: bcd

📌 三、高级字符串匹配(正则)

expr 支持通过 : 运算符配合正则表达式进行匹配。

✅ 示例 5:提取数字部分

filename="log20250623.txt"
number=$(expr "$filename" : '.*\([0-9]\+\)\.txt')
echo "文件名中的数字是: $number"

输出:

文件名中的数字是: 20250623

📌 正则解释:

  • .* 匹配任意字符直到数字前
  • \([0-9]\+\) 提取连续数字作为结果
  • \.txt 匹配 .txt 结尾

📌 四、逻辑判断与返回值

expr 的返回值遵循标准 Linux 约定:

  • 成功返回计算结果或匹配内容 → 退出码为 0
  • 出错或匹配失败 → 返回非零值

✅ 示例 6:判断是否为纯数字

input="12345"
if expr "$input" : '^[0-9]\+$' > /dev/null; then
    echo "输入是数字"
else
    echo "输入不是数字"
fi

输出:

输入是数字

📌 五、expr 与 bash 内建运算的区别

特性 expr $(( ))let
是否需要空格 必须
支持浮点数 不支持 不支持(Bash 默认也不支持)
性能 相对较慢(调用外部程序) 更快(内建)
字符串处理 强大(支持正则) 较弱
兼容性 所有 Shell 主要适用于 Bash

✅ 推荐:现代脚本优先使用 $(( )),但 expr 在字符串匹配方面仍有独特优势。


📌 六、不同 Linux 发行版上的行为差异

发行版 是否默认安装 expr 版本 备注
Ubuntu 20.04+ 是(来自 coreutils GNU expr 支持正则匹配
CentOS 7/8 GNU expr 同上
EulerOS 2.9+ GNU expr 企业级兼容良好
Alpine Linux 是(busybox 实现) busybox expr 部分正则语法不兼容

🔧 提示:Alpine 上使用 expr 时,某些正则写法可能不被支持,建议测试后再部署。


📌 七、常见问题与注意事项

  • expr 中所有操作符必须用空格隔开,否则报错
  • ⚠️ 不能处理浮点数,需借助 bc 或 Python
  • 🔄 若匹配失败,返回空字符串,注意判断方式
  • 📁 expr 是外部命令,频繁调用影响性能

📌 八、实战项目案例

📂 项目背景:日志文件按日期归档脚本

你有一个日志文件 access.log,其中每行开头是日期格式如下:

2025-06-23 12:34:56 ...
2025-06-23 12:35:01 ...
2025-06-22 10:12:03 ...

你想根据日期将日志拆分成多个文件。

✅ 使用 expr 提取日期字段并分类归档:

while read line; do
    date_str=$(expr "$line" : '\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\)')
    if [ -n "$date_str" ]; then
        echo "$line" >> "logs_$date_str.log"
    fi
done < access.log

📚 总结

通过本章学习,你应该已经掌握:

  • expr 命令的基本语法和参数含义
  • 如何在 Shell 脚本中使用 expr 进行数学运算和字符串处理
  • 利用正则表达式提取关键信息的方法
  • expr 与现代 Bash 内建运算的对比与适用场景
  • 实战中如何避免格式错误和性能陷阱

💡 提醒:虽然 expr 是一个老工具,但在字符串模式匹配和旧系统兼容方面仍具有不可替代的价值,尤其是在嵌入式环境或传统运维脚本中。


如果你还想深入了解 expr 在 Python、Go、Shell 脚本中的高级用法,请继续提问 👇

posted @ 2025-06-23 22:54  红尘过客2022  阅读(105)  评论(0)    收藏  举报