正则表达式

关注公众号 jb51net

关闭
首页 > 网络编程 > 正则表达式 > Shell正则表达式

从入门到精通Shell正则表达式实战

作者:J超会运

正则表达式是Shell编程中处理文本的核心工具,配合 grep、sed、awk 等工具可实现强大的文本查找、替换、提取功能,本教程从基础到进阶,结合大量可直接运行的示例,帮你彻底掌握Shell正则表达式,感兴趣的朋友跟随小编一起看看吧

正则表达式(Regular Expression, Regex)是 Shell 编程中处理文本的核心工具,配合 grepsedawk 等工具可实现强大的文本查找、替换、提取功能。本教程从基础到进阶,结合大量可直接运行的示例,帮你彻底掌握 Shell 正则表达式。

一、正则表达式概述与 Shell 工具支持

1. 正则表达式的类型

Shell 中主要使用三种正则规范,不同工具支持的类型不同:

类型说明支持工具
基本正则(BRE)基础元字符,部分元字符需转义grep(默认)、sed(默认)
扩展正则(ERE)更多元字符,无需额外转义grep -Esed -Eawk
Perl 兼容正则(PCRE)功能最强,支持非贪婪匹配等高级特性grep -P

2. 核心工具速览

二、基本正则表达式(BRE)

1. 基础元字符

元字符功能说明示例示例解释
^匹配行首grep '^root' /etc/passwd匹配以root开头的行
$匹配行尾grep 'bash$' /etc/passwd匹配以bash结尾的行
.匹配任意单个字符(除换行)grep 'r..t' /etc/passwd匹配rt之间有 2 个任意字符的行(如rootrbtx
*匹配前一个字符 0 次或多次grep 'ro*t' /etc/passwd匹配rtrotrootrooot
[]匹配括号内任意单个字符grep 'r[ao]t' file.txt匹配ratrot
[^]匹配不在括号内的任意字符grep 'r[^ao]t' file.txt匹配rbtrct等,但不匹配ratrot
\转义元字符,使其失去特殊含义grep 'www\.example\.com' file.txt匹配字面量www.example.com.被转义)

2. 范围匹配与重复(BRE 需转义)

在 BRE 中,以下元字符必须加 \ 转义才生效:

元字符(转义后)功能说明示例
\{n\}匹配前一个字符恰好ngrep 'ro\{2\}t' /etc/passwd匹配rooto恰好 2 次)
\{n,\}匹配前一个字符至少ngrep 'ro\{2,\}t' file.txt匹配rootrooot
\{n,m\}匹配前一个字符nmgrep 'ro\{1,3\}t' file.txt匹配rotrootrooot

三、扩展正则表达式(ERE)

使用 grep -Esed -Eawk 时,元字符无需转义,功能更强大。

1. 扩展元字符

元字符功能说明示例(用grep -E)
+匹配前一个字符 1 次或多次grep -E 'ro+t' file.txt匹配rotrootrooot(不匹配rt
?匹配前一个字符 0 次或 1 次grep -E 'ro?t' file.txt匹配rtrot
``或逻辑,匹配左右任意一个`grep -E 'rootadmin' /etc/passwd`匹配包含rootadmin的行
()分组,将多个字符视为整体grep -E '(root)+' file.txt匹配rootrootroot
{n}匹配前一个字符恰好n次(无需转义)grep -E 'ro{2}t' file.txt匹配root
{n,}匹配前一个字符至少ngrep -E 'ro{2,}t' file.txt匹配rootrooot
{n,m}匹配前一个字符nmgrep -E 'ro{1,3}t' file.txt匹配rotrootrooot

四、POSIX 字符类

为了兼容不同字符集(如中文),Shell 提供了 POSIX 字符类,需用 [[]] 包裹:

字符类说明等价于(ASCII)
[:alnum:]字母和数字[a-zA-Z0-9]
[:alpha:]字母[a-zA-Z]
[:digit:]数字[0-9]
[:lower:]小写字母[a-z]
[:upper:]大写字母[A-Z]
[:space:]空白字符(空格、制表符等)[ \t\n\r\f\v]
[:punct:]标点符号[!\"#$%&'()*+,-./:;<=>?@[\\\]^_{}~]`

示例:匹配包含数字的行

grep '[[:digit:]]' file.txt

五、实际工具应用(超详细示例)

1.grep:文本查找

基础用法

# 查找包含"error"的行(忽略大小写)
grep -i 'error' log.txt
# 查找不包含"debug"的行
grep -v 'debug' log.txt
# 显示匹配行的行号
grep -n 'root' /etc/passwd
# 递归查找当前目录下所有文件中的"TODO"
grep -r 'TODO' .

进阶:结合扩展正则

# 查找以"202"开头的年份(如2020、2021...2029)
grep -E '^202[0-9]' dates.txt
# 查找邮箱(简化版)
grep -E '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' emails.txt

2.sed:文本替换与编辑

sed 默认使用 BRE,加 -E 启用 ERE。

基础替换

# 将文件中所有"apple"替换为"orange"(直接修改文件:加-i)
sed 's/apple/orange/g' file.txt > new_file.txt
sed -i 's/apple/orange/g' file.txt  # 直接修改原文件
# 只替换第2次出现的"apple"
sed 's/apple/orange/2' file.txt

进阶:结合正则与分组

# 将"root:x:0:0:root:/root:/bin/bash"改为"User: root, Shell: /bin/bash"
# 分组\1匹配root,\2匹配/bin/bash
sed -E 's/^([a-z]+):.*:([^:]+)$/User: \1, Shell: \2/' /etc/passwd
# 删除空行
sed '/^$/d' file.txt
# 删除以#开头的注释行
sed '/^#/d' file.txt

3.awk:文本处理与数据分析

awk 默认使用 ERE,功能极其强大。

基础用法

# 打印/etc/passwd的第1列(用户名)和第7列(Shell)
awk -F: '{print $1, $7}' /etc/passwd
# 打印第3列(UID)大于1000的行
awk -F: '$3 > 1000' /etc/passwd

进阶:结合正则

# 打印以"r"开头的用户名及其Shell
awk -F: '$1 ~ /^r/ {print $1, $7}' /etc/passwd
# 统计日志中"error"出现的次数
awk '/error/ {count++} END {print "Error count:", count}' log.txt
# 提取IP地址(简化版)
awk '/([0-9]{1,3}\.){3}[0-9]{1,3}/ {print $0}' access.log

六、常见实用正则示例

1. 匹配手机号(中国大陆)

grep -E '^1[3-9][0-9]{9}$' phones.txt

2. 匹配 IP 地址(简化版,不验证合法性)

grep -E '([0-9]{1,3}\.){3}[0-9]{1,3}' ips.txt

3. 匹配日期(YYYY-MM-DD)

grep -E '^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$' dates.txt

4. 提取 HTML 中的链接(简化版)

grep -Eo 'href="[^" rel="external nofollow" ]+"' index.html | sed -E 's/href="([^" rel="external nofollow" ]+)"/\1/'

七、注意事项与避坑指南

到此这篇关于Shell正则表达式实战:从入门到精通的文章就介绍到这了,更多相关Shell正则表达式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文