• shell 阅读笔记-正则表达式与grep
    时间:2009-01-04   作者:佚名   出处:互联网

    一  正则表达式
    基本元字符集及其含义
        ^     只只匹配行首
        $     只只匹配行尾
        *     只一个单字符后紧跟*,匹配0个或多个此单字符
        [ ]   只匹配[ ]内字符。可以是一个单字符,也可以是字符序列。可以使用-
                表示[ ]内字符序列范围,如用[ 1 - 5 ]代替[ 1 2 3 4 5 ]
        \     只用来屏蔽一个元字符的特殊含义。因为有时在shell中一些元字符有
               特殊含义。\可以使其失去应有意义
        .     只匹配任意单字符
      pattern\      只用来匹配前面pattern出现次数。n为次数
      pattern\m    只含义同上,但次数最少为n
      pattern\    只含义同上,但pattern出现次数在n与m之间

    二  grep 的用法
     1 双引号引用
       在grep命令中输入字符串参数时,最好将其用双引号括起来
     2 grep选项
       常用的g r e p选项有:
       -c 只输出匹配行的计数。
       -i 不区分大小写(只适用于单字符)。
       -h 查询多文件时不显示文件名。
       -l 查询多文件时只输出包含匹配字符的文件名。
       -n 显示匹配行及行号。
       -s 不显示不存在或无匹配文本的错误信息。
       -v 显示不包含匹配文本的所有行。
     3  精确匹配
        使用grep抽取精确匹配的一种更有效方式是在抽取字符串后加\>。假定现在精确抽取48,则为"48\>"
    三 grep和正则表达式
         使用正则表达式时最好用单引号括起来,这样可以防止grep中使用的专有模式与一些shell命令的特殊方式相混淆。
      1 模式范围
        假定要抽取代码为484和483的城市位置,上一章中讲到可以使用[ ]来指定字符串范围,这里用48开始,
        以3或4结尾,这样抽出484或483。grep '48[34]' data.f
      2 不匹配行首
         如果要抽出记录,使其行首不是48,可以在方括号中使用^记号,表明查询在行首开始。
         grep '^[^48]' data.f
      3 匹配任意字符
       如果抽取以L开头,以D结尾的所有代码,可使用下述方法,因为已知代码长度为5个字符:
        grep 'L...D' data.f
      4 日期查询
        一个常用的查询模式是日期查询。先查询所有以5开始以1 9 9 6或1 9 9 8结尾的所有记录。使用模式5..199[6,8].这意味着第一个字符为

        5,后跟两个点,接着是199,剩余两个数字是6或8。
         grep '5..199[6,8]' data.f
        查询包含1998的所有记录的另外一种方法是使用表达式[0-9]\[8],含义是任意数字重复3次,后跟数字8,虽然这个方法不像上一个方

       法那么精确,但也有一定作用。
      5 使用grep匹配“与”或者“或”模式
        grep命令加- E参数,这一扩展允许使用扩展模式匹配。例如,要抽取城市代码为2 1 9或2 1 6,方法如下:
        grep -E '219|216' data.f
      6 空行
       结合使用^和$可查询空行。使用- n参数显示实际行数:
        grep '^$' data.f
      7 grep 与类名的使用
       类等价的正则表达式类等价的正则表达式
      [[:upper:]]   [A-Z]               [[:alnum:]]  [0-9a-zA-Z]
      [[:lower:]]   [a-z]               [[:space:]] 空格或t a b键
      [[:digit:]]   [0-9]                [[:alpha:]] [a-zA-Z]


    用‘grep’搜索文本文件

    如果您要在几个文本文件中查找一字符串,可以使用‘grep’命令。‘grep’在文本中搜索指定的字符串。

    假设您正在‘/usr/src/linux/Documentation’目录下搜索带字符串‘magic’的文件:

    $ grep magic /usr/src/linux/Documentation/*

    sysrq.txt:* How do I enable the magic SysRQ key?

    sysrq.txt:* How do I use the magic SysRQ key?

    其中文件‘sysrp.txt’包含该字符串,讨论的是 SysRQ 的功能。

    默认情况下,‘grep’只搜索当前目录。如果此目录下有许多子目录,‘grep’会以如下形式列出:

    grep: sound: Is a directory

    这可能会使‘grep’的输出难于阅读。这里有两种解决的办法:

    明确要求搜索子目录:grep -r

    或忽略子目录:grep -d skip

    当然,如果预料到有许多输出,您可以通过 管道 将其转到‘less’上阅读:

    $ grep magic /usr/src/linux/Documentation/* | less

    这样,您就可以更方便地阅读。

    有一点要注意,您必需提供一个文件过滤方式(搜索全部文件的话用 *)。如果您忘了,‘grep’会一直等着,直到该程序被中断。如果您遇到了这样的情况,按 ,然后再试。

    命令行参数:

    grep -i pattern files :不区分大小写地搜索。默认情况区分大小写,

    grep -l pattern files :只列出匹配的文件名,

    grep -L pattern files :列出不匹配的文件名,

    grep -w pattern files :只匹配整个单词,而不是字符串的一部分(如匹配‘magic’,而不是‘magical’),

    grep -C number pattern files :匹配的上下文分别显示[number]行,

    grep pattern1 | pattern2 files :显示匹配 pattern1 或 pattern2 的行,

    grep pattern1 files | grep pattern2 :显示既匹配 pattern1 又匹配 pattern2 的行。

    这里还有些用于搜索的特殊符号:



    \< 和 \> 分别标注单词的开始与结尾。
    例如:
    grep man * 会匹配 ‘Batman’、‘manic’、‘man’等,
    grep '\<man' * 匹配‘manic’和‘man’,但不是‘Batman’,
    grep '\<man\>' 只匹配‘man’,而不是‘Batman’或‘manic’等其他的字符串。



    '^':指匹配的字符串在行首,'$':指匹配的字符串在行尾,如果您不习惯命令行参数,可以试试图形界面的‘grep’,如 reXgrep .这个软件提供 AND、OR、NOT 等语法,还有漂亮的按钮 .如果您只是需要更清楚的输出,不妨试试 fungrep .

    结合find和grep来搜索多个目录中的文件内容。

    # find / -name "*.txt" -print

    / :find 命令从目录/开始搜索并搜索所有源于它的子目录

    -name :指明搜索的名字或名字模式,查找所有以。txt结尾的文件

    -print :表明find命令应输出其搜索到的和标准相匹配的文件名

    # find -name "*.txt" -print -exec grep test {} \;

    grep test {} \; :-exec参数的一部分。每次找到和-name参数中指定的条件相匹配的文件时,用来搜索单词test的grep命令将被执行。

    {} :参数告诉find命令每次执行-exec部分的命令时插入匹配文件的完整路径和文件名。

    \; :表示find每次找到一个匹配文件时其所执行的-exec部分的命令结束。

    网友留言/评论

    我要留言/评论