Linux 系统中文本处理“三剑客”之grep
我们写脚本的时候,经常要截取命令输出的某项数据,比如:我要知道主机上有多少块硬盘
这是很方便的。使用grep搜索出我们想要的数据再使用 sed 、或 cup 切割就可以取得我们主机的设备名称了,这是我们取数据的一种方法。
Egreq 是grep 的升级版,支持扩展表达式、fgrep不支持正则表达式。
使用格式:
1
2
3
4
5
|
grep [OPTIONS] PATTERN [FILE...] -o 只打印输出匹配到字符串 -i 做匹配时候忽略大小写 - v 打印输出不匹配的内容 -E 表示支持扩展表达式 |
【grep】是文本搜索工具,逐行读入文本,按照给定的模式(pattern)做匹配,查看行中的单词/字符是否与“模式”相匹配。默认匹配到的行会输出到监视器。
程序一般有数据的输入和输出,也称为程序的IO。从这个角度来分析,grep 程序数据的输入可以是文件(从磁盘中读取数据)或从标准输入(也就是它可以使用管道作为grep 的数据输入的。)
使用【grep】命令的时候,不指定文件,它就从标准输入读取数据了。
【grep】默认是把匹配到模式的行输出到标准输出的。
Grep 是文本搜索工具,只处理文本。所以,我们在做查找目录文件的时候,先要使用【ls】把目录中的内容列出来,再使用 grep 做文本搜索处理。
目录文件搜索,使用 Bash shell 中的元字符。
简单地了解下,文件通配与正则表达式的区别?
列出 /etc 目录中以 .conf 或 .d 结尾的文件。
是做字符(串)的匹配呢,还是做单词的匹配呢?
加上词尾锚定后,只有单词的词尾与给定的“模式”匹配,grep 才会获取到。如果单词的
中间或前面与“模式”匹配,grep 不会显示出来。
如下述匹配模式加上词尾锚定后,不会显示aliases.db 文件了。
总结:
使用【grep】的时候,要注意:文件的通配符和正则表式的元字符有很多看似一样,但它们表示的特殊意义是不尽相同的。很容易混淆的。
使用【grep】搜索文本的时候,分析思路总结:
1、 分析匹配的内容
是做单词匹配呢、还是做字符(串)匹配呢。
A、如果匹配的内容是单词的话,需要使用词首锚定符(\<)和词尾锚定符(\>)标识写 在模式中的字串不是字符串而是单词。
B、如果匹配的内容是字符(串)的话,就直接把匹配内容做为grep匹配模式就可以了。
也就是字符串搜索。
2、 确定匹配的位置
是行首还是行尾、词首、还是词尾、还是任意位置
A、正则表达式提供了一些元字符来表示:在一行文本中要匹配的位置。
如:行首锚定符(^)、行尾锚定符($)、词首锚定符(\<)、词尾锚定符(\>) 这些都统称为锚(目标点)。
B、如果,正则表达式中没有这些锚定符的话,正则表达式在一行文本中要匹配的位置就是字符(串)。
3、是否要修饰匹配内容呢?
它们用于展开或缩小(即是修改了)正则表达式匹配文本行的范围。修饰符包括了星号(*)、括号()、
反斜杠符号、问号。这些都可以称为修饰符。是用来修饰匹配内容的。
既然我们的匹配内容,分为单词和字符,则有必要了解一下,在grep中何为单词?
理解grep 中所谓的单词对于我们熟悉运用该命令来做文本搜索很有帮助。
对【grep】的定义的单词的理解
Grep 对单词的定义:
单词:不包含特殊字符的连续字符组成的串叫单词。
如上图所示,我们使用【grep】搜索文本b.txt 中的单词save。就可以很好地知道,在 grep 世界中,所谓的“单词”是什么。图中显示红色的就是save单词。
“连续”指的是:字符串间没有空格,且字符串没有特殊字符(中括号,大括号,问号等)。也可以说特殊字符是单词的分界。
那么,在实现应用中如何使用【grep】搜索文本找出我们需要的内容呢?
1、【grep】对字符的匹配。
分析:做匹配的位置是否有要求? 无
找出包含字符s的行 不需要修改。
所以,我们的可以写成:grep “s” FILE
正则表达式在一行文本中要匹配的位置是字符。所以会拿文本行的每一个字符都做正则表达式匹配。
Grep 命令读取一行,行中的每个字符都与“模式”做匹配动作。
如果匹配了就显示高亮显示匹配到的字符。如下图所示。
例:找出文件a.txt中ab字符中出现一个或零个s字符的行
匹配内容是字符,所以不需要词首锚定符和词尾锚定符标识。
匹配的位置无要求,所以不需要使用位置锚定符。
匹配内容ab间的s字符无法确定所以要使用修饰符(?)。
问号(?),修饰符:表示前面的字符出现的次数为0次或1次。如下图所示:
分析,我们做字符匹配,grep 拿来与给定模式做匹配的就不是单词了,而是字符。
在这里,grep 读取每一个字符就与模式做匹配操作。看看读取到的字符是不是 a ,如果是字符 a 就判断 a 字符后是一个或没有字符 s ,如果 a 字符后面符合特殊字符(\?)的要求,而取得的下一个字符又是字符 b ,就代表刚才读取字符 a至字符 b, 这间这段字符串与给定的模式相匹配了。
2、【grep】做单词匹配。
找出包含单词save的行。
分析:
匹配的内容是“单词”,所以要使用词首锚定符和词尾锚定符标识。
匹配的位置无要求,所以不需要使用位置锚定符。
正则表达式在一行文本中要匹配的位置为单词。无论是“词首锚定”还是“词尾锚定”。很显然,grep 每次取一个“单词”与“模式”做匹配,匹配到的就高亮显示正则表达式,
使用“词首锚定符\<”和“词尾锚定符\>”标识一个单词的。
3、【grep】做行匹配. 正则表达式在一行文本中要匹配的位置为行尾或行首。
我们的匹配有“单词匹配”和“字符匹配”,所以我们指定的条件可以为:
A、以某个字符开头的行
B、以某个字符结尾的行
C、以某个单词开头的行
D、以某个单词结尾的行
分析,上图所示。找出,以单词 save 打头的行。
第一步,先匹匹配到包含单词 save 的行。
第二步,使用“行首锚定符 ^”告诉 grep 我们做的是行匹配的操作,所以
第二次使用 grep 做文本搜索的时候,只会显示以单词 save 开头的行。
注意:
我们使用 grep 做文本搜索的时候,要特别注意空白,特别是在行尾。如下图所示:
第一次使用 grep 搜索的时候没有匹配到什么行。
第二次假设 字符串 LISTEN 后面跟有空格再换行,就搜索到匹配的行了。