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


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

    wKioL1PCeFLxxHMSAABsWZrIneo226.jpg

    这是很方便的。使用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】命令的时候,不指定文件,它就从标准输入读取数据了。

    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】搜索文本找出我们需要的内容呢?

    1、【grep】对字符的匹配。

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

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

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

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

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

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


    wKioL1PCe8KADGxvAACbPHZLNV8379.jpg

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

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

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

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

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

    wKiom1PCfE2QrY1bAADPztN0gUI641.jpg

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

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

    2、【grep】做单词匹配。

    找出包含单词save的行。

    分析:

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

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

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

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


    wKioL1PCfIuwyHzaAADHKrE4tAc853.jpg

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

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

       A、以某个字符开头的行

       B、以某个字符结尾的行

       C、以某个单词开头的行

       D、以某个单词结尾的行

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

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

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

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

    注意:

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

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

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

    wKiom1PCfWzh8nBeAAEyZy1jbIM068.jpg

    如何将快播种子转换为迅雷种子

  • 相关阅读:
    Oracle并行操作——从串行到并行
    Log4Net使用指南
    NET开发人员应该要知道
    测试11g压缩性能
    C#不同操作系统下,界面大小不一的原因
    采用nettcp绑定的wcf宿主到iis7
    Packaging Oracle Data Access Components into .Net projects
    Operating System Property Values
    【转】《Effective C#中文版:改善C#程序的50种方法》读书笔记
    解决.svc 无法解析
  • 原文地址:https://www.cnblogs.com/nbjk/p/3842385.html
Copyright © 2020-2023  润新知