Shell编程之正则表达式与文本处理器

Source

一.正则表达式

正则表达式的定义

  • 正则表达式(Regular Expression , 简称RE):又称正则表达式、常规表达式。
  • 使用字符串来描述匹配一切符合某个规则的字符串
正则表达式组成
  • 普通字符:大小写字母、数字、标点符号
  • 元字符:在正则表达式中具有特殊意义的专用字符
概念 定义 适用场景
正则表达式(Regex) 用于匹配文本模式的字符串规则,是通用的文本匹配语法 grep、sed、awk、find(-regex 参数)等
通配符(Glob) Shell 自带的文件名匹配语法(文本表达式的一种) ls、cp、rm 等文件操作命令(匹配文件名)

关键区别:正则表达式匹配文件内容,通配符匹配文件名;比如 * 在通配符中表示 “任意字符”,在正则中表示 “前一个字符重复 0 次或多次”。

二、正则表达式基础语法(POSIX 标准)

Shell 中常用的正则分为两类:基础正则表达式(BRE)扩展正则表达式(ERE),核心语法如下:

1. 基础元字符(BRE/ERE 通用)

元字符 含义 示例
. 匹配任意单个字符(除换行符) h.t 匹配 hat、hot、h1t
^ 匹配行首 ^hello 匹配以 hello 开头的行
$ 匹配行尾 world$ 匹配以 world 结尾的行
[] 匹配括号内任意一个字符 [abc] 匹配 a、b、c;[0-9] 匹配数字
[^] 匹配括号内以外的任意字符 [^0-9] 匹配非数字字符
\ 转义符(取消元字符特殊含义) \. 匹配小数点,而非任意字符
* 前一个字符重复 0 次或多次 ab* 匹配 a、ab、abb、abbb...

2. 扩展元字符(ERE,需加参数启用)

BRE 中需加 \ 转义(如 \+),ERE 可直接使用,常用工具中:

  • grep:加 -E 参数启用 ERE(等价于 egrep)

  • sed:加 -r 参数启用 ERE

  • awk:默认支持 ERE

元字符 含义 示例
+ 前一个字符重复 1 次或多次 ab+ 匹配 ab、abb、abbb...(不匹配 a)
? 前一个字符重复 0 次或 1 次 ab? 匹配 a、ab(不匹配 abb)
` ` 或匹配 `a b匹配a或b;(hello) (world)` 匹配 hello 或 world
() 分组匹配 (ab)+ 匹配 ab、abab、ababab...
{n} 前一个字符重复 n 次 a{3} 匹配 aaa
{n,} 前一个字符重复至少 n 次 a{2,} 匹配 aa、aaa、aaaa...
{n,m} 前一个字符重复 n 到 m 次 a{2,4} 匹配 aa、aaa、aaaa

三、Shell 中常用文本处理工具(结合正则)

1. grep:文本过滤(最常用)

核心功能:按正则匹配文本行,输出匹配结果。

常用参数:
  • -e:启用扩展正则(等价于 egrep)

  • -i:忽略大小写

  • -v:反向匹配(输出不匹配的行)

  • -n :表示显示行号

  1. 利用中括号“[ ]”来查找集合字符
  • 在[ ]中无论有几个字符,一次只能代表一个字符
  • ^在[ ]:表示以什么什么开头
例如1:
同时要找shirt和short时
【io】:表示匹配“i”或者“o”
例如2:
要查找包含重复单个字符时
例如3:
不以w开头
因为不止一个oo,oo前面还是oo
例如4:
不以小写字母开头
例如5:
不以数字开头
  1. 查找行首“^”与行尾字符“$”
  • ^在[ ]:表示以什么什么开头
  • $:表示以什么什么结尾
例如1:
查找以小写字母开头
例如2:
查找及不包含小写字母也不包含大写字母
例如3:
用转义字符(/)
例如4:
查找空白行(^$)
  1. 查找任意一个字符“.” 与重复字符“*”
  • 在正则表达式中小数点(.)也是一个元字符,代表任意一个字符
  • *:代表的时重复零个或多个前面的单字符
o*:表示拥有零个(即空字符)或大于等于一个“o”的字符,允许字符为空
oo*:第一个o必须存在,第二个o则是零个或多个o
例如1:
查找以 w开头 d结尾
例如2:
查询以w开头,的结尾,中间包含至少一个o的字符串
例如3:
查询以w开头,d结尾,中间的字符可有可无
例如4:
查询任意数字所在行
  1. 查找连续子符范围“{}”
例如1:
查询两个o的字符
例如2:
查询以w开头以d结尾,中间包含2~5个o的字符串
例如3:
查询以w开头以d结尾,中间包含2个或2个以上o的字符串

元字符总结

四.文本处理器

sed:文本编辑(流编辑器)

核心功能:按正则匹配文本并修改(替换、删除、新增等),默认输出到终端,不修改原文件。

sed的工作流程:

  • 读取:sed从输入流(文件、管道、标准输入)中读取一行内容并存储到临时的缓冲区中(又称空间模式,pattern sapce)
  • 执行:默认情况下,所有的sed命令都在模式空间中顺序的执行,除非指定的行地址,否则sed命令将会在所有的行上依法执行
  • 显示:发送修改后的内容到输出流。在发送数据后,模式空间将会被清空

常用参数:

  • -e或--expression=:表示用指定命令或者脚本来处理输入的文本文件
  • -f 或--file:表示用指定的脚本文件来处理输入的文本文件
  • -h或--help:显示帮助
  • -n、--quiet或silent:表示仅显示处理后的结果
  • -i:直接编辑文本文件
  • a:增加,在当前行面增加一行指定内容
  • c:替换,选定行替换为指定内容
  • d:删除,删除选定的行
  • i:插入,在选定行面插入一行指定内容
  • p:打印
  • s:替换,替换指定字符
  • y:字符转换

用法示例

  1. 输出符合条件的文本(p表示正常输出)
例如1:
输出文本:sed -n 'p' test.txt
  • -n:显示处理后的结果
  • p:打印
例如2:
输出 指定行:sed -n '3p' test.txt
  • 3p:表示输出文本的第三行
输出 多个指定行:sed -n '3,5p' test.txt
  • 3,5p:表示输出文本的第三行到第五行
输出 所有奇数行
sed -n 'p;n' test.txt
  • p;n:表示输出所有奇数行,n表示读入下一行资料
sed -n '1,5{p;n}' test.txt
  • 1,5{p;n}:表示输出文本第1~5的奇数行
输出 所有偶数行
sed -n 'n;p' test.txt
  • n;p:表示输出所有偶数行,n表示读入下一行资料
sed -n '10,${n;p}' test
  • 10,${n;p}:表示输出第10行至文件末尾的偶数行
例如3:正则表达式以“/”包围
输出包含the的行
例如4:
输出从第4行至第一个包含the的行
例如5:
输出包含the的行所在的行号,等号(=)用来输出行号
例如6:
输出以PI开头的行
例如7“
输出数字结尾的行
例如8:
输出包含单词wood的行,\<、\>代表单词边界
  1. 删除符合条件的文本(d)
  • nl:用于计算文件的行数
例如1:
删除第3行:nl test.txt |sed '3d'
删除第3~5行: nl test.txt | sed '3,5d'
删除以小写字母开头的行:sed '/^[a-z]/d' test.txt
删除以”.“结尾的行:sed /\.$/d' test.txt
删除所有空行:sed '/^$/d' test.txt
  1. 替换符合条件的文本
  • s:字符串替换
  • c:整行/整块替换
  • y:字符转换
例:
将每行中的第一个the替换为THE: sed 's/the/THE' test.txt
将每行中的第2个i替换成L: sed 's/i/L/2' test.txt
将文件中所有the替换成The : sed 's/the/The/g' test.txt
将文件中所有的o删除(替换为空串): sed 's/o//g' test.txt
在每行行首插入#号: sed 's/^/#/' test.txt
在包含the的每行行首插入#号: sed '/the/s/^/#/' test.txt
在每行行尾插入字符串EOF : sed 's/$/EOF/' test.txt
将第3~5行中的所有the替换成THE :sed '3,5s/the/THE/g' test.txt
将包含the的所有行中的o都替换成O: sed '/the/s/o/O/g' test.txt
  1. 迁移符合条件的文本
常用参数:
H:复制到剪贴板
g、G:将剪贴板中的数据覆盖/追加至指定行
w:保存为文件
r:读取指定文件
a:追加指定内容
将包含the的行迁移至文件末尾,{;}用于多个操作:sed '/the/{H;d};$G' test.txt
将第1~5行内容转移至第17行后: sed '1,5{H;d};17G' test.txt
读取指定的文件后添加包含the的每行以后: sed '/the/r /etc/hostname' test.txt
在第3行后插入多行内容,中间的\n表示换行: sed '3aName1\name2' test.txt
在第3行后插入一行新行,内容为New: sed '/the/aNew' test.txt

五.awk工具

  • 功能强大的编辑工具
  • 五交互的情况下实现复杂的文本操作

核心功能:按列 / 行处理文本,默认按空格 / 制表符分割列,支持正则匹配、逻辑判断、计算等。

基本语法:awk '条件{动作}' 文件名
常用内置变量:
  • $0:整行内容
  • $1-$n:第 1 到第 n 列的内容
  • NF:当前行的列数
  • NR:当前行的行号
  • FS:指定每行文本的字段分割符,默认为空格或指标搁

按行输出文本

总结:

  • 核心区别:正则表达式匹配文本内容,通配符匹配文件名,二者语法不同(如*的含义);
  • 常用工具:grep 用于过滤文本、sed 用于编辑文本、awk 用于分析文本,均支持正则,需掌握各自核心参数;
  • 关键语法:基础正则的^/$/./[],扩展正则的+/?/|/{}是高频使用的元字符,需熟练记忆。