【shell】正则表达式

一、正则表达式基础概念

正则表达式(Regular Expression,简称Regex)是用于文本模式匹配的表达式语言,广泛应用于Shell工具(如grepsedawk)及编程语言中。其核心作用包括:

  • 文本搜索:快速定位符合特定模式的字符串
  • 文本替换:批量修改符合模式的文本
  • 数据验证:检查输入是否符合格式要求

二、正则表达式语法分类

在Shell环境中,主要涉及两种正则语法:

  1. 基本正则表达式(BRE)​
    • 默认模式(grepsed默认使用)
    • 部分元字符需转义(如\+\?
  2. 扩展正则表达式(ERE)​
    • 使用-Eegrepawk启用
    • 支持更多元字符(如+?|等)

三、核心元字符速查表
元字符作用BRE示例ERE示例
锚定
^匹配行首^start相同
$匹配行尾end$相同
字符匹配
.匹配任意单个字符(除换行符)a.c → "abc"相同
[abc]匹配括号内的任意字符gr[ae]y → "gray"/"grey"相同
[^abc]匹配不在括号内的字符[^0-9] → 非数字相同
量词
*前一个元素0次或多次go*d → "gd"/"good"相同
\+前一个元素1次或多次go\+d → "god"/"good"+(无需转义)
\?前一个元素0或1次colou\?r → "color"/"colour"?(无需转义)
{n,m}匹配次数范围a\{2,4\} → "aa"/"aaa"/"aaaa"{2,4}(无需转义)
分组与逻辑
$...$捕获分组$ab$\+ → "abab"(...)(无需转义)
|逻辑或不支持apple|banana
特殊序列
\d数字(部分工具支持)需工具支持[0-9]的简写
\s空白字符需工具支持[ \t\n\r]的简写
\b单词边界\bword\b → 独立单词相同

四、Shell工具中的正则应用
1. ​grep
# 基本正则(默认)
grep 'error: [0-9]\+' log.txt       # 匹配"error: 123"格式

# 扩展正则(-E或egrep)
egrep 'ERROR|WARNING' log.txt       # 匹配ERROR或WARNING
grep -E '^[A-Z]{3}-\d{4}' codes.txt # 匹配如ABC-1234的代码
2. ​sed
# 替换操作(使用基本正则)
sed 's/$http:\/\/$example/\1newexample/' file.txt

# 扩展正则(-r选项)
sed -r 's/(\d{4})-(\d{2})/\2\/\1/' dates.txt # 2023-09 → 09/2023
3. ​awk
# 匹配整行
awk '/^192\.168/ {print $1}' access.log      # 匹配以IP开头的行

# 匹配字段
awk '$2 ~ /^[A-Z][a-z]+$/ {print $0}' data.csv  # 第2列是首字母大写的单词
4. ​find
# 按正则匹配文件名
find . -regex '.*/backup_[0-9]{8}\.tar\.gz$'  # 查找backup_20230901.tar.gz

五、常用模式示例
1. 邮箱地址验证
grep -E '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$' emails.txt
2. 匹配IPv4地址
egrep '((25[0-5]|2[0-4][0-9]|[01]?[0-9]{1,2})\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]{1,2})' log.txt
3. 提取日期时间
# 匹配YYYY-MM-DD HH:MM:SS格式
sed -nE 's/.*([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}).*/\1/p' logfile
4. 删除HTML标签
sed 's/<[^>]*>//g' webpage.html
 5、基本匹配
  1. 匹配包含特定字符串的行

    • 查找包含“root”字符串的行:cat /etc/passwd | grep root
  2. 匹配以特定字符开头的行

    • 查找以“a”字符开头的行:cat /etc/passwd | grep ^a
  3. 匹配以特定字符结尾的行

    • 查找以“e”字符结尾的行:cat /etc/passwd | grep e$
  4. 匹配任意单个字符

    • 查找以“r”开头,“t”结尾,中间包含任意两个字符的行:cat /etc/passwd | grep r..t
  5. 匹配特定范围内的字符

    • 查找包含数字6或8的行(这里使用了方括号表示字符范围):cat /some/file | grep [68]

    • 查找包含一个0到9之间的数字的行:cat /some/file | grep [0-9]

6、特殊字符和转义
  1. 匹配任意长度的数字字符串

    • 使用星号(*)匹配任意长度的数字字符串:cat /some/file | grep [0-9]*
  2. 匹配特定字符并转义

    • 查找包含“”符号的行(需要使用反斜杠进行转义):‘cat/scripts/nt​est.sh∣grep′ '`
  3. 匹配不包含特定字符串的行

    • 使用grep的-v选项查找不包含“QP”字符串的行:ls -lR ./OutResult/ | grep -v 'QP'
7、分组和预搜索
  1. 分组匹配

    • 使用圆括号进行分组匹配,并提取文本中的一部分内容。例如,查找以“a”开头,“in”结尾,中间包含任意字符的行,并提取中间的内容:cat /etc/passwd | grep '^a.*in$'(注意,这里并没有直接提取中间内容,但分组的概念可以用于更复杂的正则表达式中)
  2. 正向预搜索

    • 使用正向预搜索(?=pattern)查找不匹配特定模式的字符串开始处。例如,查找不以“QP”开头的以“svac2”结尾的行:ls -lR | grep -E '((?!QP).).*svac2$'
8、实际案例
  1. 归档脚本中的正则表达式

    • 在归档脚本中,可以使用正则表达式来匹配和过滤文件名。例如,根据日期模式匹配归档文件名:FILE=archive_${DIR_NAME}_$(date +%y%m%d).tar.gz
  2. 使用awk和cut进行文本处理

    • 结合awk和cut命令,使用正则表达式进行文本处理。例如,使用awk提取passwd文件中以“root”开头的行的第七列:cat /etc/passwd | awk -F ":" '/^root/ {print $7}'

    • 使用cut命令从文件中剪切数据。例如,从passwd文件中提取以“bash”结尾的行的第一、六、七列:cat /etc/passwd | grep bash | cut -d ":" -f 1,6,7

  1. 匹配以 hello 开头的行:

    grep '^hello' filename
  2. 匹配以 world 结尾的行:

    grep 'world$' filename
  3. 匹配包含 a 或 b 的行(注意:在基本正则表达式中,| 需要通过 egrep 或 grep -E 来支持):

    egrep 'a|b' filename
    # 或者
    grep -E 'a|b' filename
  4. 匹配包含数字的行:

    grep '[0-9]' filename
  5. 匹配不包含字母的行(即只包含数字、空格或其他非字母字符):

    grep '^[^a-zA-Z]*$' filename
  6. 匹配以 a 开头,后面跟着任意数量的字符,再以 z 结尾的行:

    grep '^a.*z$' filename

六、调试与优化技巧
  1. 在线测试工具

    • RegExr
    • Regex101
  2. 调试方法

    # 分阶段测试正则组件
    echo "test123" | grep '^[a-z]\+[0-9]\+$'
    
    # 使用echo验证替换效果
    echo "price: $5.99" | sed 's/\$$[0-9]\+$\.$[0-9]\+$/\1元\2角/'
  3. 性能优化

    • 避免使用.*的贪婪匹配
    • 优先使用具体字符集(如[0-9]代替\d
    • 使用锚定符缩小匹配范围

七、注意事项
  1. 工具差异

    • awk默认使用ERE且不支持\d
    • grep -P启用PCRE(Perl兼容正则,需GNU grep)
  2. 转义规则

    • Shell本身会解析反斜杠,需双重转义:
      # 匹配单个反斜杠需要写成四个反斜杠
      echo "path: C:\\Windows" | grep 'C:\\\\Windows'
  3. 可读性维护

    • 复杂正则添加注释(部分工具支持(?x)忽略空格和注释):
      grep -P '(?x)^
          \d{3}       # 前三位数字
          -?          # 可选分隔符
          \d{2}       # 中间两位
          -?          # 可选分隔符
          \d{4}       # 最后四位
      $' ssn.txt

通过掌握这些正则表达式技巧,可以高效处理以下场景:

  • 日志分析(提取关键错误信息)
  • 数据清洗(格式化不规则数据)
  • 配置管理(批量修改配置文件)
  • 输入验证(检查用户输入格式)

建议结合具体工具手册(man 7 regex)深入学习正则表达式的高级特性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浩瀚之水_csdn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值