欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > Shell 编程之正则表达式与文本处理器

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

2025/4/19 10:02:28 来源:https://blog.csdn.net/2302_79408199/article/details/147259164  浏览:    关键词:Shell 编程之正则表达式与文本处理器

目录

基础正则表达式

        正则表达式的定义

        元字符总结

        扩展正则表达式

sed 工具使用方法

        sed基本语法 

awk 工具使用方法

        awk有两种语法格式


基础正则表达式

        正则表达式的定义

        正则表达式又称正规表达式、常规表达式。在代码中常简写为 regex、regexp 或 RE。正则表达式是使用单个字符串来描述、匹配一系列符合某个句法规则的字符串,简单来说,是一种匹配字符串的方法,通过一些特殊符号,实现快速查找、删除、替换某个特定字符串。

        正则表达式是由普通字符与元字符组成的文字模式。模式用于描述在搜索文本时要匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。其中普通字符包括大小写字母、数字、标点符号及一些其他符号,元字符则是指那些在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符)在目标对象中的出现模式。

        正则表达式一般用于脚本编程与文本编辑器中。很多文本处理器与程序设计语言均支持正则表达式,例如 Linux 系统中常见的文本处理器(grep、egrep、sed、awk)以及应用比较广泛的 Python 语言。正则表达式具备很强大的文本匹配功能,能够在文本海洋中快速高效地处理文本。

          语法如下:

\

转义字符,取消特殊符号的含义

^

匹配字符串的开始位置,如:^word匹配以word开头的行

$

匹配字符串的结束位置,如:word$匹配以word结尾的行

.

匹配除 \n (换行)之外的任意一个字符

*

匹配前面的子表达式0次或者多次

[list]

匹配list列表中的一个字符,如:[0-9] 匹配任一位数字

[^list]

匹配不在list列表中的一个字符,如:[^0-9] 匹配任意一位非数字字符

\{n\}

匹配前面的子表达式n次,如:[0-9]\{2\} 匹配两位数字 

\{n,\}

匹配前面的字表达式不少于n次,如:[0-9]\{2,\} 表示两位及两位以上数字

\{n,m\}

匹配前面的字表达式n到m次,如:[a-z]\{2,3\} 匹配两到三位的小写字母

         如下以grep命令实例:

grep  root  /etc/passwd				//筛选文件中包含root的行
grep  ^root  /etc/passwd				//筛选以root开头的行
grep  bash$  /etc/passwd				//筛选以bash结尾的行
grep  -v  root  /etc/passwd			//筛选文中不包含root的行
grep  'r..d'  /etc/passwd				//筛选出r 和d 之间有两个字符的行
grep  '[^s]bin'  /etc/passwd			//筛选bin前面不是s的行
grep  '^$'  /etc/passwd				//筛选出空白行
grep  't[es]'  /etc/passwd				//筛选包含字符串te或ts的行
grep  '0\{1,\}'  /etc/passwd				//筛选数字0出现1次或1次以上的行
grep  -e  'ntp'  -e  'root'  /etc/passwd			// -e参数查找多个模式
grep  [0-3]  /etc/passwd				//筛选包含数字0-3的行
grep  '[^a-z]ae'  /etc/passwd			//筛选ae前面不是小写字母的行
grep  '^[a-z]ae'  /etc/passwd			//筛选ae前面是小写字母的行grep  'the'  1.txt 				//过滤出包含  the  的行
grep -n  'the'  1.txt			//过滤出包含  the  的行,显示行号
grep -ni  'the'  1.txt 			//过滤出包含  the  的行,显示行号,不区分大小写
grep -vn  'the'  1.txt			//过滤出不包含 the 的行,显示行号
grep -n  'sh[io]rt'  1.txt		//过滤出包含 shirt  和short的行
grep -n  'oo'  1.txt 			//过滤出包含oo的行
grep -n  '[w]oo'  1.txt			//过滤出oo前面是 w的行
grep -n  '[^w]oo'  1.txt		//过滤出oo前面不是 w 的行
grep -n  '[^a-z]oo'  1.txt 		//过滤出oo前面不是小写字母的行
grep -n  '[0-9]'  1.txt 			//过滤出包含任意一位数字的行
grep -n  '^the'  1.txt 			//以the开头的行
grep -n '[a-z]'  1.txt 			//过滤出包含任意一位小写字母的行
grep -n  '[^a-z]'  1.txt			//过滤出任意一位不是小写字母的行
grep -n  '^[a-z]'  1.txt			//过滤出以小写字母开头的行
grep -n  '^[A-Z]'  1.txt			//过滤出以大写字母开头的行
grep -n  '[a-zA-Z]'  1.txt		//过滤出包含任意一位字母的行
grep -n  '[^a-zA-Z]'  1.txt			//过滤出任意一位不是字母的行
grep -n  [^a-zA-Z]  1.txt			//过滤出任意一位不是字母的行
grep -n  '^[^a-zA-Z]'  1.txt			//过滤出开头不是字母的行
grep -n  '[\.$]'  1.txt 				//过滤出以  .  结尾的行
grep -n  '^$'  1.txt 				//过滤出空行
grep -n  'w..d'  1.txt 				//过滤出w和d中间有两位字符
grep -n 	'ooo*'  1.txt 				//过滤出2个以上的o的行
grep -n  'woo*d'  1.txt				//过滤出w和d中间有1个以上的o	
grep -n  'w.*d'  1.txt 				//过滤出w和d中间有0个以上的字符
grep -n  '[0-9][0-9]'  1.txt			//过滤出任意2位数字的行
grep -n  '[0-9][0-9]*'  1.txt			//过滤出任意1位以上的数字
grep -n  'o\{2\}'  1.txt 				//过滤出包含2个o的行
grep -n  'wo\{2,5\}d'  1.txt			//过滤出w和d中间有2-5个o
grep -n  'wo\{2,\}d'  1.txt 			//过滤出w和d中间有2个以上的o

        元字符总结

\将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符
^匹配输入字符串的开始位置
$匹配输入字符串的结束位置
*匹配前面的子表达式要次或多次
+匹配前面的子表达式一次或多次
?匹配前面的子表达式零次或一次
.匹配除换行符(\n、w)之外的任何单个字符
[a-z]字符范围。匹配指定范围内的任意字符。
{n}n 是一个非负整数,匹配确定的n次
{n,}n是一个非负整数,至少匹配n 次
{n,m}m 和n均为非负整数,其中n<= m。最少匹配n次且最多匹配 m 次
\d匹配一个数字字符。等价于 [0-9]。
\D匹配一个非数字字符。等价于[^0-9]。
\s匹配任何空白字符,包括空格、制表符、换页符等等。等价于[\fn\r\t\v]。
\S匹配任何非空白字符。等价于[^ \fn\nt\v]。
\w匹配字母、数字、下划线。等价于'[A-Za-z0-9_]'
\W匹配非字母、数字、下划线。等价于'[^A-Za-z0-9_]'.
\n匹配一个换行符
\f匹配一个换页符
\r匹配一个回车符

        扩展正则表达式

+

匹配前面的子表达式1次以上,如:go+d,将匹配至少一个o

匹配前面的字表达式0次或者1次,如:go?d,将匹配gd或god

()

将 () 号中的字符串作为一个整体,如:(xyz)+,将匹配xyz整体1次以上

|

以或的方式匹配字符串,如:good|great,将匹配good或者great

()+辨别多个重复的组,如:egrep -n 'A(xyz)+C' test.txt,将查询开头的“A”结尾是“C”,中间有一个以上的“xyz”字符串的意思

        以egrep为例:

egrep  0+  /etc/passwd				//匹配至少包含一个0的行
egrep  '(root|ntp)'  /etc/passwd			//匹配包含root或ntp的行
egrep  ro?t  /etc/passwd				//匹配rt或者rot的行
egrep  -v  '^$|^#'  /etc/passwd			//过滤文件中的空白行与#开头的行

sed 工具使用方法

        sed(stream Epitor)是一个强大而简单的文本解析转换工具,可以读取文本,并根据指定的条件对文本内容进行编辑(删除、替换、添加、移动等),最后输出所有行或者仅输出处理的某些行。sed 也可以在无交互的情况下实现相当复杂的文本处理操作,被广泛应用于 Shel1 脚本中,用以完成各种自动化处理任务。

        sed 的工作流程主要包括读取、执行和显示三个过程。

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

        sed基本语法 

sed [选项] '操作' 参数

sed [选项] -f scriptfile 参数

例如:

sed -e ‘编辑指令’ 文件1 文件2  ……

sed -n ‘编辑指令’ 文件1 文件2 ……

sed -i ‘编辑指令’ 文件1 文件2 ……

常用的sed 命令选项主要包含以下几种:

  • -e 或--expression=:表示用指定命令或者脚本来处理输入的文本文件。
  • -f或--file=:表示用指定的脚本文件来处理输入的文本文件。
  • -h或--help:显示帮助。
  • -n、--quiet 或 silent:表示仅显示处理后的结果。
  • -i:直接编辑文本文件。

         “操作”用于指定对文件操作的动作行为,也就是 sed 的命令。通常情况下是采用的“[n1[,n2]]”操作参数的格式。n1、n2 是可选的,代表选择进行操作的行数,如操作需要在 5~20 行之间进行,则表示为“5,28 动作行为”。常见的操作包括以下几种。

  • a:增加,在当前行下面增加一行指定内容。
  • c:替换,将选定行替换为指定内容。
  • d:删除,删除选定的行。
  • i:插入,在选定行上面插入一行指定内容。
  • p:打印,如果同时指定行,表示打印指定行;如果不指定行,则表示打印所有内容;如果有非打印字符,则以 ASCII 码输出。其通常与“-n”选项一起使用。
  • s:替换,替换指定字符。
  • y:字符转换。
  • r:读取指定文件
  • w:保存为文件

        以sed 为例:

    sed  -n  'p'  /etc/passwd					//将所有内容输出sed  -n  '6p'  /etc/passwd					//将第6行内容输出sed  -n  '6,8p'  /etc/passwd				//将第6~8行内容输出sed  -n  'p;n'  /etc/passwd				//将所有奇数行输出sed  -n  'n;p'  /etc/passwd				//将所有偶数行输出sed  -n  '1,10{p;n}'  /etc/passwd			//将1~10行中的奇数行输出sed  -n  '1,10{n;p}'  /etc/passwd			//将1~10行中的偶数行输出sed  -n  '10,${n;p}'  /etc/passwd			//将10~末尾之间的奇数行输出
p;n:从第1行开始是奇数,从第2行开始是偶数
n;p:从第1行开始是偶数,从第2行开始是奇数sed  -n  '/root/p'  /etc/passwd				//将匹配包含root的行进行输出sed  -n  '10,/mon/p'  /etc/passwd			//将从第10行至第一个包含mon的行进行输出,如果没有mon,则从第十行输出到最后一行 sed  -nr  '/ro{1,}t/p'  /etc/passwd			//匹配不少于1次前导字符o,
加 –r 参数支持拓展正则表达式sed  -n  '/root\|ntp/p'  /etc/passwd			//输出包含root或者ntp的行sed  -n  '/mon/='  /etc/passwd				//将包含mon所在的行的行号输出“=”号用来输出行号
插入:sed  -e  '5q'  /etc/passwd					//输出前5行信息后退出,q退出sed  '/root/i  aaaaaaa'  /etc/passwd			//在含有root行的前一行添加aaaaaaased  '/root/a  aaaaa'  /etc/passwd			//在含有root行的后一行添加aaaaased  '3a  ADMIN'  /etc/passwd				//在第3行后面插入一行ADMIN删除:sed  '1d'  /etc/passwd						//删除第1行sed  '$d'  /etc/passwd						//删除最后1行sed  '/^$/d'  etc/passwd					//删除空行sed  '2,4d'  /etc/passwd					//删除第2~4行sed  '/root/d'  /etc/passwd					//删除含有root的行sed  '/root/!d'  /etc/passwd				//删除不包含root的行,!:表示取反sed  '/^root/d'  /etc/passwd				//删除以root开头的行sed  '/nologin$/d'  /etc/passwd				//删除以nologin结尾的行替换:sed  's/root//g'  /etc/passwd				//将文件中所有的root都删除sed  '/root/c  aaaaa'  /etc/passwd			//将含有root的行替换为aaaaased  -n  's/root/admin/2p'  /etc/passwd		//将每行的第二个root替换成admin
sed  '/root/s/root/ROOT/g'  /etc/passwd																			//将包含root行的所有行中的root替换为ROOTsed 	'1,3s/bin/BIN/g' 	/etc/passwd			//将第1~3行中的所有bin都替换为BINsed  's/^/#/'  /etc/passwd					//在每行行首插入 # 号sed  's/$/ABC/'  /etc/passwd				//在每行行尾插入字符 ABCsed  '/root/s/^/#/'  /etc/passwd				//将包含root的行的行首插入 # 号sed  '1c ABC'  /etc/passwd					//将第一行替换为 ABCsed  'y/rot/ROT/'  /etc/passwd			//将rot替换为ROT	//  y表示应替换sed  '1,10y/root/ROOT/'  /etc/passwd		//将第1~10行中的root对应替换为ROOT迁移:	h:表示保存当前模式到一个缓冲区G:将剪贴板中的数据追加至指定行H:复制到剪贴板g:将剪贴板中的数据覆盖到指定行w:保存为文件sed  '/root/w file1'  /etc/passwd			//将对应root行另存为文件file1sed	 '/root/{H;d};$G'	 /etc/passwd			//将包含root的行迁移到末尾sed  '1,5{H;d};$G'  /etc/passwd				//将第1~5行内容迁移到末尾执行多次命令:Sed  -ne  's/root/admin/'  -ne  's/bash/sh/p'  /etc/passwd//将root和bash行作替换
-e可以将多个命令连接起来,也可将多个编辑命令保存到文件中,通过-f指定文件,来完成多个处理操作直接修改文件内容:sed  -i  's/^/#/'  /etc/passwd			//在每行开头插入 # 号,直接修改原文件sed  -i  's/^#//g'  /etc/passwd			//将每行开头的 # 号删除,直接修改原文件

awk 工具使用方法

        awk逐行读取文本,默认以空格为分隔符进行分隔,将分隔所得的各个字段保存到内建变量中,对比该行是否与给定的模式相匹配,并按模式或者条件执行编辑命令,也可以从脚本中调用编辑指令过滤出相应内容。

        awk有两种语法格式

        awk 【选项】 ‘模式或条件 {编辑指令}’  文件1  文件2

        awk -f  脚本文件        文件1        文件2 

        awk 包含几个特殊的内建变量(可直接使用)如下:

FS指定每行文本的字段分隔符,默认为空格或制表位。
NF当前处理的行的字段个数。
NR当前处理的行的行号(序数)。
$0当前处理的行的整行内容。
$n当前处理行的第n个字段(第n列)。
FILENAME被处理的文件名。
RS数据记录分隔,默认为\n,即每行为一条记录,

        例如:awk

        awk  '/^root/ {print}'  /etc/passwd                //输出以root开头的行
        awk  '/nologin$/ {print}'  /etc/passwd                //输出以nologin结尾的行
        awk  -F  ":"  '/bash$/ {print |"wc -l"}'  /etc/passwd    //统计可登录系统用户的个数

         awk:可以使用关系运算符作为“条件”,用于比较数字与字符串,只有条件为真,才执行指定的动作。

>

<

>=

<=

==

!=

&&

||

!

+

-

*

/

%

^

大于

小于

大于等于

小于等于

等于

不等于

取余

乘方

        例如:

    awk  'NR==1,NR==3 {print}'  /etc/passwd				//输出第1行至第3行内容awk  'NR==1||NR==3 {print}'  /etc/passwd				//输出第1,3行内容awk  'NR==1,NR==3 {print}'  /etc/passwd				//输出第1行至第3行内容awk  '(NR%2)==1 {print}'  /etc/passwd				//输出所有奇数行的内容awk  '(NR%2)==0 {print}'  /etc/passwd				//输出所有偶数行的内容awk  -F  :  '!($3<900) {print}'  /etc/passwd		//输出第3个字段不小于900的行//“!”号表示取反awk:可以使用条件表达式,条件表达式的运算涉及两个符号,冒号和问号,实质就是if...else语句的捷径,有着和if...else相同的效果。awk  -F  :  '{if($3>200) {print $0}}'  /etc/passwd		//输出第3个字段大于200的行awk  -F  :  '{max=($3>$4)?$3:$4;print max}'  /etc/passwd 		
//如果第3个字段的值大于第4个字段的值,则把冒号前表达式的值赋给max,否则就将冒号后那个表达式的值赋给maxawk  -F  :  '{max=($3>200)?$3:$1;print max}'  /etc/passwd
//如果第3个字段的值大于200,则把第3个字段的值赋给max,否则就把第1个字段的值赋给max按字段输出:awk  -F  :  '{print NR,$0}'  /etc/passwd		//输出行号和整行内容awk  -F  :  '$3<5 {print $1 $3}'  /etc/passwd	//输出第3列小于5的第1列与第3列数据awk  -F  :  'NR==3,NR==7 {print $1,$7}'  /etc/passwd//输出第3行到第7行中以冒号为分隔符的第1列与第7列的数据awk  -F  ":"  '($1~"root")&&(NF==7){print $1,$3}'  /etc/passwd//输出包含7个字段,并且第1个字段中包含root的行的第1与第3个字段内容需要的话,输出数据时还可以插入一些文本标签:awk  -F  ":"  '{print $1":"$2":"$3":"$4}'  /etc/passwd//保留原来的格式,输出以冒号为分隔的前4个字段awk  -F  :  '{print $1,$3}'  /etc/passwd			//以冒号为分隔符,输出第1,3列awk  'BEGIN{FS=":"}{print $1,$3}'  /etc/passwd		//以冒号为分隔符,输出第1,3列//在FS之前加一个BEGIN,当读取第一条数据之前,先把分隔符加上后再去操作。awk  'BEGIN{X=0};/\/bin\/bash$/{X++};END{print X}'  /etc/passwd//统计以/bin/bash为结尾的行数awk执行顺序:	先执行BEGIN{ }中的操作;再从指定的文件中逐行读取数据,自动更新NF、NR、$0、$1等内建变量的值,去s执行'模式或条件{编辑指定}';最后指定END{ }中的后续操作。处理命令输出的结果:awk可以利用管道符“|”处理命令的结果date  | awk  '{print "Month:"$2"\nYear:",$6}'

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词