首页 > 代码库 > Linux 系统中文本处理“三剑客”之grep

Linux 系统中文本处理“三剑客”之grep

我们写脚本的时候,经常要截取命令输出的某项数据,比如:我要知道主机上有多少块硬盘

wKioL1PCeFLxxHMSAABsWZrIneo226.jpg

这是很方便的。使用grep搜索出我们想要的数据再使用 sed 、或 cup 切割就可以取得我们主机的设备名称了,这是我们取数据的一种方法。

Egreq grep 的升级版,支持扩展表达式、fgrep不支持正则表达式。

使用格式:

grep [OPTIONS] PATTERN [FILE...]
     -o     只打印输出匹配到字符串
     -i      做匹配时候忽略大小写
     -v      打印输出不匹配的内容
     -E      表示支持扩展表达式

grep】是文本搜索工具,逐行读入文本,按照给定的模式(pattern)做匹配,查看行中的单词/字符是否与“模式”相匹配。默认匹配到的行会输出到监视器。

程序一般有数据的输入和输出,也称为程序的IO。从这个角度来分析,grep 程序数据的输入可以是文件(从磁盘中读取数据)或从标准输入(也就是它可以使用管道作为grep 的数据输入的。)

使用【grep】命令的时候,不指定文件,它就从标准输入读取数据了。

wKioL1PCeTCTeTDaAABB7Bd6Rec533.jpg

grep】默认是把匹配到模式的行输出到标准输出的。

Grep 是文本搜索工具,只处理文本。所以,我们在做查找目录文件的时候,先要使用【ls】把目录中的内容列出来,再使用 grep 做文本搜索处理。

目录文件搜索,使用 Bash shell 中的元字符。

 

简单地了解下,文件通配与正则表达式的区别?

列出 /etc 目录中以 .conf .d 结尾的文件。

wKiom1PCebWjTwGEAAGWd6yB1rs834.jpg

是做字符()的匹配呢,还是做单词的匹配呢?

wKioL1PCedWj8C6FAAH1pvUpt9s102.jpg

加上词尾锚定后,只有单词的词尾与给定的“模式”匹配,grep 才会获取到。如果单词的

中间或前面与“模式”匹配,grep 不会显示出来。

如下述匹配模式加上词尾锚定后,不会显示aliases.db 文件了。

wKiom1PCekfAUQVxAAI6nV0HyD0809.jpg

总结:

使用【grep】的时候,要注意:文件的通配符和正则表式的元字符有很多看似一样,但它们表示的特殊意义是不尽相同的。很容易混淆的。

使用【grep】搜索文本的时候,分析思路总结:

1、  分析匹配的内容

是做单词匹配呢、还是做字符()匹配呢。

   A如果匹配的内容是单词的话,需要使用词首锚定符(\<)和词尾锚定符(\>)标识写         在模式中的字串不是字符串而是单词。

   B如果匹配的内容是字符()的话,就直接把匹配内容做为grep匹配模式就可以了。

   也就是字符串搜索。

2、  确定匹配的位置

   是行首还是行尾、词首、还是词尾、还是任意位置

   A、正则表达式提供了一些元字符来表示:在一行文本中要匹配的位置。

  如:行首锚定符(^)、行尾锚定符($)、词首锚定符(\<)、词尾锚定符(\>) 这些都统称为锚(目标点)

  B、如果,正则表达式中没有这些锚定符的话,正则表达式在一行文本中要匹配的位置就是字符()

3、是否要修饰匹配内容呢?

   它们用于展开或缩小(即是修改了)正则表达式匹配文本行的范围。修饰符包括了星号(*)、括号()

   反斜杠符号、问号。这些都可以称为修饰符。是用来修饰匹配内容的。


    既然我们的匹配内容,分为单词和字符,则有必要了解一下,在grep中何为单词?

理解grep 中所谓的单词对于我们熟悉运用该命令来做文本搜索很有帮助。

对【grep】的定义的单词的理解

wKioL1PCe2HjQMh4AACU1T6iGDQ056.jpg

Grep 对单词的定义:

单词:不包含特殊字符的连续字符组成的串叫单词。

   如上图所示,我们使用【grep】搜索文本b.txt 中的单词save。就可以很好地知道,在 grep 世界中,所谓的“单词”是什么。图中显示红色的就是save单词。

   “连续”指的是:字符串间没有空格,且字符串没有特殊字符(中括号,大括号,问号等)。也可以说特殊字符是单词的分界。


那么,在实现应用中如何使用【grep】搜索文本找出我们需要的内容呢?

1grep对字符的匹配。

分析:做匹配的位置是否有要求?       

      找出包含字符s的行              不需要修改。

所以,我们的可以写成:grep “s”  FILE

正则表达式在一行文本中要匹配的位置是字符。所以会拿文本行的每一个字符都做正则表达式匹配。

Grep 命令读取一行,行中的每个字符都与“模式”做匹配动作。

如果匹配了就显示高亮显示匹配到的字符。如下图所示。


wKioL1PCe8KADGxvAACbPHZLNV8379.jpg

例:找出文件a.txtab字符中出现一个或零个s字符的行

匹配内容是字符,所以不需要词首锚定符和词尾锚定符标识。       

匹配的位置无要求,所以不需要使用位置锚定符。

匹配内容ab间的s字符无法确定所以要使用修饰符(?)

问号(?),修饰符:表示前面的字符出现的次数为0次或1次。如下图所示:

wKiom1PCfE2QrY1bAADPztN0gUI641.jpg

分析,我们做字符匹配,grep 拿来与给定模式做匹配的就不是单词了,而是字符。

在这里,grep 读取每一个字符就与模式做匹配操作。看看读取到的字符是不是 a ,如果是字符 a 就判断 a 字符后是一个或没有字符 s ,如果 a 字符后面符合特殊字符(\?)的要求,而取得的下一个字符又是字符 b ,就代表刚才读取字符 a至字符 b, 这间这段字符串与给定的模式相匹配了

 

2grep做单词匹配。

找出包含单词save的行。

分析:

匹配的内容是“单词”,所以要使用词首锚定符和词尾锚定符标识。

匹配的位置无要求,所以不需要使用位置锚定符。

正则表达式在一行文本中要匹配的位置为单词。无论是“词首锚定”还是“词尾锚定”。很显然,grep 每次取一个“单词”与“模式”做匹配,匹配到的就高亮显示正则表达式,

使用“词首锚定符\<”和“词尾锚定符\>”标识一个单词的。


wKioL1PCfIuwyHzaAADHKrE4tAc853.jpg

3grep做行匹配. 正则表达式在一行文本中要匹配的位置为行尾或行首。

   我们的匹配有“单词匹配”和“字符匹配”,所以我们指定的条件可以为:

   A、以某个字符开头的行

   B、以某个字符结尾的行

   C、以某个单词开头的行

   D、以某个单词结尾的行

分析,上图所示。找出,以单词 save 打头的行。

第一步,先匹匹配到包含单词 save 的行。

第二步,使用“行首锚定符 ^告诉 grep 我们做的是行匹配的操作,所以

      第二次使用 grep 做文本搜索的时候,只会显示以单词 save 开头的行。

注意:

我们使用 grep 做文本搜索的时候,要特别注意空白,特别是在行尾。如下图所示:

第一次使用 grep 搜索的时候没有匹配到什么行。

第二次假设 字符串 LISTEN 后面跟有空格再换行,就搜索到匹配的行了。

wKiom1PCfWzh8nBeAAEyZy1jbIM068.jpg

本文出自 “Linux” 博客,请务必保留此出处http://9528du.blog.51cto.com/8979089/1437658