linux正则表达式


因为在之前说过grep指令支持正则表达式,因此在次使用grep来进行学习

一、正则表达式基础

1、查找特定的字符串

  为grep的基本功能,之前已经说过了,主要是通过指令grep  'strname' filename

2、使用[]来查找集合字符

  []代表的是某一个字符,而其中使用的式限定该字符的规则,其中使用[^]代表与某规则相反,如下说是^e的结果就是啥也看不到,相应的规则表达形式在后续总结。

3、行首与行尾字符^$

  为了在已经筛选完成的结果中进一步筛选,如列出查找的字符在句首的行显示出来,那么可以使用^来进行筛选,与上面的[^]存在区别,为了进一步说明区别grep -n '^[^a-zA-Z]'  log_complex.txt 的意思为找到不以字母开头的行,第一个^代表的就是行首,第二个[^]代表的就是取反,在[]内部和外部的^的意思是不一样的

  对于查找词在句尾的时候可以使用$来进行查找,但是如下所示windows下的断行符并不仅仅隐藏$结尾,其隐藏的为^M$,但是这个^M不是字符不可进行匹配操作,不可使用查找,而在linux下为.$,在linux中.字符有特殊的意义,因此需要使用转义字符\.$

4、任意一个字符.与重复的字符*

  .(小数点):代表一定有一个任意字符。

  *(星号):代表重复前面的字符0到n次,为组合形态。注意这是正则表达式。

  在之前讲过shell的通配符,其中:

       * :匹配任意多个字符(包括零个或一个)与正则表达式存在区别
  ? :匹配任意一个字符(不包括零个)

   例如使用grep 'g*g' text.txt查找包含以g开头和以g结尾的字符串,如下所示,实际上缺少了一个’.‘,应当的输入为grep 'g.*g' text.txt,所有问题的根源在于*正则表达式可以表示前一个字符0个元素,相当于直接消除了前面的元素。使用’.‘在’*‘之前相当于没有消除前一个字符。

 5、使用连续RE字符范围

  4中找出的是任意多的字符,那么需要找到限定的字符数量该如何操作?如上面的找2~5个o在gd之间。此时就需要使用范围限定字符{},由于{}在shell中有特殊意义,因此需要使用转义字符\配合使用,如在上述的结果中查找在字符gd之间包含两个以上的o的goo*d形式的行的操作为: grep -n 'go\{2,5\}'d text.txt

  上下限可以不指明表示不少于和不多于,例如查找在字符gd之间包含不少于2个o的行可以使用 grep -n 'go\{2,\}  text.txt'

6、总结

正则表达式的特殊字符与一般命令行输入的通配符是不一样的!

^word:待查找的字符串(word)在行首。

word$:带查找的字符串(word)在行尾。

 . :一定代表一个任意字符

*:代表0~n个与前一个字符重复的字符

[list]:表示从集合集的RE字符中找到想要选取的字符

[n1-n2]:从集合集的RE字符中找到想要选取的字符范围,但是要明确语系的,不然范围的选择会出现问题

[^list]:表示从集合的RE字符中找到不要的字符串和范围。

\{start,end\}:start或者end可以省略一个,若接该内容的最后一个字符为o,则表示限定o字符出现的次数为start与end之间。

在list的选择中会由于编码语系的影响而造成一定的问题,因为有的编码是a,b,c...z但是有的却是a,A,b,B,c,C....z,Z,因此为了避免编码问题带来的集合的错选,有一些特殊的符号可以使用

[:alnum:]:0-9,A-Z,a-z

[:aipha:]:A-Z,a-z

[:blank:]:空格和键值

[:cntr:]:代表键盘上的控制按键,包括del、contrl等

[:digit:]:代表数字

[:graph:]:除了空格与tab键意外的其他所有按键

[:lower:]:a-z

[:punct:]:代表标点符号

[:upper:]:大写的A-Z

[:xdigit:]:代表16进制的数字类型,包括0-9,a-z,A-Z

[:print:]:任何可以被打印出来的字符

注意下面的错误,一定在外面另加一个[],也就是说需要[[:pattern:]],下面是查找一个包含16进制字符的以9结尾的行。

查询满足s(标点)t的行

使用print标准查找

 

使用上述方法查询在etc文件夹下的链接文件

7、sed工具

  sed的作用可以对标准输入进行处理,包括替换删除、新增、选定特定行的功能。可以看到sed类似于filter能够对输入流进行编辑,过滤。

 语法规则是:sed [-nefr] [动作]

   -n :在一般的sed用法中,所有的标准输入都会被列在屏幕上,但是在该模式下,只有经过特殊处理的才会被显示

  -e :直接在命令行模式上进行sed的动作编辑

  -f:直接讲sed的动作写在一个文件内,-f filename 则是可以执行filename内的sed动作

  -r :sed 的动作支持的是拓展型正则表达式的语法(默认式基础的正则表达式语法)

  -i:直接修改读取的文件内容,而不是在屏幕输出

动作说明: n1,n2 function 代表在n1 和n2之间执行function

function:

a:增加,后面可以接字符串,这些字符会在新的一行出现。

c:替换,后面可以接字符串,这些字符串可以替换n1与n2之间的所有的行。

d:删除,通常不接任何内容。

p:打印内容

i:插入,i后面可以接字符串,这些字符串会插入当前行的上一行。

s:替换,可以进行替换工作,通常这个动作可以搭配正则表达式。

使用function d 进行删除8-9行的内容。

同样的删除10行以后的所有行,其中$代表最后一行,所有的操作并不会影响到原始文件,因为其仅仅能够处理流数据。

在某一行进行添加使用a,可以使用\进行多行的输入,一定到有空格!a是在制定行后,i为指定行前。

将2-4行替换为NO 2-4 number字符串,实际上可以看到行号都没有了,直接替换了。

打印选定的行使用function p 但是问题在于-n 安静模式,实际上不使用-n有很大的输出影响,即为选定的行会重复输出。

在进行文本的替换使用‘s/要被替换的内容/新的字符串/g’

使用组合替换删除,使用grep选出所需要操作的行,使用seed对选出的行进行删除等操作

之前的所有操作都不具备更改原始文件的能力,为了增加sed对原始文件的修改能力使用-i参数,例如 sed -i 's/test/change/g' text.txt ,关键在于使用-i需要后接文件,也不难以理解,因为你毕竟需要改动源文件。

在使用-i 进行添加a的时候会另起一行,为了能够在行首或者行尾添加内容还是需要使用替换模式s

二、拓展正则表达式

  之前的正则表达式都需要处理完一个操作后才能接另一个操作,例如grep -v 'string1' filename|grep -v 'string2'  filename十分冗长,因此有可以讲这两句合并,合并的语句为 egrep -v 'string1|string2' filename这样就可以达到相同的目的,由于grep默认是不支持拓展正则表达式的,因此要使用egrep来支持拓展正则表达式。

cat log_complex.txt|grep -v 'Epoch'|grep -v 'This fpr'

cat log_complex.txt|egrep -v 'Epoch|This fpr'

拓展的正则表达式的其他支持的操作有:

+:重复一个或者一个以上的前一个RE字符,注意与基本正则表达式*的区别。

?:重复0个或者1个前一个RE字符。

|:使用或的方式找出数个字符串

():找到组字符串

()+:多个重复组的判别

 egrep 'go+d' text.txt :顺利的找到了符合要求的行,但是没有找gd

 

egrep 'go?d' text.txt:找到了gd和god,使用.对比一下区别能够看到区别

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM