MemoryGarden's Blog

努力 -----------大能猫

C++博客 首页 新随笔 联系 聚合 管理
  118 Posts :: 11 Stories :: 20 Comments :: 0 Trackbacks
                                                              下载
                                 第8章 grep 家 族
   相信 g r e p是 U N I X和 L I N U X中使用最广泛的命令之一。 g r e p(全局正则表达式版本)允许
对文本文件进行模式查找。如果找到匹配模式, grep打印包含模式的所有行。 grep支持基本正
则表达式,也支持其扩展集。 grep有三种变形,即:
   Grep:标准 grep命令,本章大部分篇幅集中讨论此格式。
   E g r e p :扩展 g r e p,支持基本及扩展的正则表达式,但不支持 \ q 模式范围的应用,与之相
对应的一些更加规范的模式,这里也不予讨论。
   F g r e p:快速 g r e p 。允许查找字符串而不是一个模式。不要误解单词 f a s t,实际上它与 g r e p
速度相当。
   在本章中我们将讨论:
   • grep(参数)选项。
   • 匹配 grep的一般模式。
   • 只匹配字母或数字,或两者混用。
   • 匹配字符串范围。
   实际上应该只有一个 grep 命令,但不幸的是没有一种简单形式能够统一处理 grep的三种变
形,将之合而为一,并保持 g r e p 单模式处理时的速度。 GNU grep 虽然在融合三种变形上迈进
了一大步,但仍不能区分元字符的基本集和扩展集。上一章只讨论了基本的正则表达式,但
在查看 g r e p时也涉及到一些扩展模式的匹配操作。然而,首先还是先讨论一下在 g r e p 和 f g r e p
及egrep中均可使用的 grep模式吧。
   开始讨论之前,先生成一个文件,插入一段文本,并在每列后加入 <Tab>键, g r e p命令示
例中绝大多数将以此为例,其命名为 data..f。生成一个文件,但不知其含义,将是一件很枯燥
的事。那么先来看看 data.f的记录结构。
   第1列:城市位置编号。
   第2列:月份。
   第3列:存储代码及出库年份。
   第4列:产品代号。
   第5列:产品统一标价。
   第6列:标识号。
   第7列:合格数量。
                                                          57
                                            第8章 grep 家 族
  下载
8.1 grep
      grep一般格式为:
      grep [ 选项 ]基本正则表达式 [文件 ]
      这里基本正则表达式可为字符串。
8.1.1 双引号引用
      在g r e p命令中输入字符串参数时,最好将其用双引号括起来。例如: m y s t r i n g”
                                                   “      。这样做
 有两个原因,一是以防被误解为 s h e l l命令,二是可以用来查找多个单词组成的字符串,例如:
“ jet plane ” ,如果不用双引号将其括起来,那么单词 p l a n e 将被误认为是一个文件,查询结果
 将返回“文件不存在”的错误信息。
      在调用变量时,也应该使用双引号,诸如: g r e p“ $MYVAR ”文件名,如果不这样,将
 没有返回结果。
      在调用模式匹配时,应使用单引号。
 8.1.2 grep选项
      常用的 grep选项有:
      -c 只输出匹配行的计数。
      -i 不区分大小写(只适用于单字符)       。
      -h 查询多文件时不显示文件名。
      -l 查询多文件时只输出包含匹配字符的文件名。
      -n 显示匹配行及行号。
      -s 不显示不存在或无匹配文本的错误信息。
      -v 显示不包含匹配文本的所有行。
 8.1.3 查询多个文件
      如果要在当前目录下所有 .doc文件中查找字符串“ sort”      ,方法如下:
      $ grep "sort"*.doc
      或在所有文件中查询单词“ sort it ”
      $ grep "sort it" *
      现在讲述在文本文件中 grep选项的用法。
 8.1.4 行匹配
      $ grep -c "48"data.f
      $4
      grep返回数字 4,意义是有 4行包含字符串“ 48”。
      现在显示包含“ 48”字符串的 4行文本:
    58           第二部分 文 本 过 滤
                                                           下载
 8.1.5 行数
         显示满足匹配模式的所有行行数:
         行数在输出第一列,后跟包含 48的每一匹配行。
 8.1.6 显示非匹配行
         显示所有不包含 48的各行:
8.1.7 精确匹配
         可能大家已注意到,在上一例中,抽取字符串“ 4 8 ”    ,返回结果包含诸如 4 8 4和4 8 3 等包含
“ 48”的其他字符串,实际上应精确抽取只包含 48的各行。注意在每个匹配模式中抽取字符串
后有一个 <Tab>键,所以应操作如下:
         <Tab>表示点击 tab键。
         使用 g r e p抽取精确匹配的一种更有效方式是在抽取字符串后加 \ > 。假定现在精确抽取 4 8 ,
方法如下:
8.1.8 大小写敏感
         缺省情况下, g r e p是大小写敏感的,如要查询大小写不敏感字符串,必须使用 - i开关。在
d a t a . f 文件中有月份字符 S e p t,既有大写也有小写,要取得此字符串大小写不敏感查询,方法
 如下:
 8.2 grep和正则表达式
         使用正则表达式使模式匹配加入一些规则,因此可以在抽取信息中加入更多选择。使用
正则表达式时最好用单引号括起来,这样可以防止 g r e p 中使用的专有模式与一些 s h e l l 命令的
特殊方式相混淆。
                                                              59
                                              第8章 grep 家 族
 下载
8.2.1 模式范围
     假定要抽取代码为 484和483的城市位置,上一章中讲到可以使用 [] 来指定字符串范围,这
里用 48开始,以 3或4结尾,这样抽出 484或483。
8.2.2 不匹配行首
     如果要抽出记录,使其行首不是 48,可以在方括号中使用 ^记号,表明查询在行首开始。
8.2.3 设置大小写
     使用 - i 开关可以屏蔽月份 S e p t的大小写敏感,也可以用另一种方式。这里使用 [ ]模式抽取
各行包含 Sept和sept的所有信息。
     如果要抽取包含 S e p t 的所有月份,不管其大小写,并且此行包含字符串 4 8 3,可以使用管
道命令,即符号“ |”左边命令的输出作为“ |”右边命令的输入。举例如下:
     不必将文件名放在第二个 grep命令中,因为其输入信息来自于第一个 grep命令的输出。
8.2.4 匹配任意字符
     如果抽取以 L开头,以 D 结尾的所有代码,可使用下述方法,因为已知代码长度为 5 个字
符:
     将上述代码做轻微改变,头两个是大写字母,中间两个任意,并以 C结尾:
8.2.5 日期查询
     一个常用的查询模式是日期查询。先查询所有以 5开始以 1 9 9 6 或1 9 9 8结尾的所有记录。使
用模式 5 . . 1 9 9 [ 6 , 8 ]。这意味着第一个字符为 5 ,后跟两个点,接着是 1 9 9 ,剩余两个数字是 6或
8。
   60   第二部分 文 本 过 滤
                                                                    下载
     查询包含 1 9 9 8 的所有记录的另外一种方法是使用表达式 [ 0 - 9 ] \ { 3 \ } [ 8 ] ,含义是任意数字重
复3次,后跟数字 8,虽然这个方法不像上一个方法那么精确,但也有一定作用。
8.2.6 范围组合
     必须学会使用 []抽取信息。假定要取得城市代码,第一个字符为任意字符,第二个字符在
0到5之间,第三个字符在 0到6之间,使用下列模式即可实现。
     这里返回很多信息,有想要的,也有不想要的。参照模式,返回结果是正确的,因此这
里还需要细化模式,可以以行首开始,使用 ^符号:
     这样可以返回一个预期的正确结果。
8.2.7 模式出现机率
     抽取包含数字 4至少重复出现两次的所有行,方法如下:
     上述语法指明数字 4至少重复出现两次。
     同样,抽取记录使之包含数字 999(三个 9)   ,方法如下:
     如果要查询重复出现次数一定的所有行,语法如下,数字 9重复出现两次:
     有时要查询重复出现次数在一定范围内,比如数字或字母重复出现 2 到6 次,下例匹配数
字8重复出现 2到6次,并以 3结尾:
                                                                61
                                               第8章 grep 家 族
  下载
8.2.8 使用grep匹配“与”或者“或”模式
     g r e p 命令加 - E 参数,这一扩展允许使用扩展模式匹配。例如,要抽取城市代码为 2 1 9 或
216,方法如下:
8.2.9 空行
     结合使用 ^和$可查询空行。使用 -n 参数显示实际行数:
8.2.10 匹配特殊字符
     查询有特殊含义的字符,诸如$ . ' " * [] ^ | \ + ? ,必须在特定字符前加\。假设要查询包含“.”
的所有行,脚本如下:
     或者是一个双引号:
     以同样的方式,如要查询文件名 conftroll.conf(这是一个配置文件)          ,脚本如下:
8.2.11 查询格式化文件名
     使用正则表达式可匹配任意文件名。系统中对文本文件有其标准的命名格式。一般最多
六个小写字符,后跟句点,接着是两个大写字符。例如,要在一个包含各类文件名的文件
filename.deposit 中定位这类文件名,方法如下:
8.2.12 查询IP地址
     查询 D N S 服务是日常工作之一,这意味着要维护覆盖不同网络的大量 I P 地址。有时地址
I P 会超过 2 0 0 0个。如果要查看 n n n . n n n 网络地址,但是却忘了第二部分中的其余部分,只知有
两个句点,例如 nnn.nn..。要抽取其中所有 nnn.nnn IP 地址,使用 [0-9]\{3\}\.[0-0\{3\}\。含义是
任意数字出现 3次,后跟句点,接着是任意数字出现 3次,后跟句点。
  62           第二部分 文 本 过 滤
                                                                 下载
8.3 类名
   grep允许使用国际字符模式匹配或匹配模式的类名形式。
                           表8-1 类名及其等价的正则表达式
       类             等价的正则表达式                 类     等价的正则表达式
   [[:upper:]]          [A-Z]           [[:alnum:]]  [0-9a-zA-Z]
                                                     空格或 tab键
   [[:lower:]]          [a-z]           [[:space:]]
   [[:digit:]]          [0-9]           [[:alpha:]]  [a-zA-Z]
   现举例说明其使用方式。要抽取产品代码,该代码以 5 开头,后跟至少两个大写字母。使
用的脚本如下:
   如果要抽取以 P或D 结尾的所有产品代码,方法如下:
使用通配符*的匹配模式
   现在讲述 grep中通配符 *的使用。现有文件如下:
   下述 grep模式结果显示如下:
   如在行尾查询某一单词,试如下模式:
   这将在所有文件中查询行尾包含单词 device的所有行。
8.4 系统grep命令
   使用已学过的知识可以很容易通过 g r e p 命令获得系统信息。下面几个例子中,将用到管
                                                             63
                                             第8章 grep 家 族
  下载
道命令,即符号 |,使用它左边命令的输出结果作为它右边命令的输入。
8.4.1 目录
     如果要查询目录列表中的目录,方法如下:
     如果在一个目录中查询不包含目录的所有文件,方法如下:
     要查询其他用户和其他用户组成员有可执行权限的目录集合,方法如下:
8.4.2 passwd文件
上述脚本查询 /etc/passwd文件是否包含 louise字符串,如果误输入以下脚本:
将返回 grep命令错误代码 'No such file or directory' 。
     上述结果表明输入文件名不存在,使用 grep命令 -s开关,可屏蔽错误信息。
返回命令提示符,而没有文件不存在的错误提示。
     如果 grep命令不支持 -s开关,可替代使用以下命令:
脚本含义是匹配命令输出或错误( 2 > $ 1 )          ,并将结果输出到系统池。大多数系统管理员称
/dev/null为比特池,没关系,可以将之看成一个无底洞,有进没有出,永远也不会填满。
     上述两个例子并不算好,因为这里的目的只想知道查询是否成功。本书后面部分将讨论
grep命令的 exit用法,它允许查询并不成功返回。
     如要保存 grep命令的查询结果,可将命令输出重定向到一个文件。
     脚本将输出重定向到目录 /tmp下文件 passwd.out中。
8.4.3 使用ps命令
     使用带有 ps x 命令的 g r e p可查询系统上运行的进程。 ps x 命令意为显示系统上运行的所有
进程列表。要查看 DNS服务器是否正在运行(通常称为 named)            ,方法如下:
     输出也应包含此 g r e p 命令,因为 g r e p命令创建了相应进程, ps x 将找到它。在 g r e p命令中
使用 -v 选项可丢弃 ps命令中的 grep进程。
   64          第二部分 文 本 过 滤
                                                                                       下载
     如果 ps x 不适用于用户系统,替代使用 ps -ef。
8.4.4 对一个字符串使用grep
     g r e p不只应用于文件,也可应用于字符串。为此使用 e c h o字符串命令,然后对 g r e p命令使
用管道输入。
匹配成功实现。
因为没有匹配字符串,所以没有输出结果。
8.5 egrep
     e g r e p代表 e x p r e s s i o n或extended grep ,适情况而定。 e g r e p接受所有的正则表达式, e g r e p
的一个显著特性是可以以一个文件作为保存的字符串,然后将之传给 e g r e p作为参数,为此使
用-f开关。如果创建一个名为 grepstrings 的文件,并输入 484和47:
     上述脚本匹配 d a t a . f中包含 4 8 4或 4 7的所有记录。当匹配大量模式时, - f开关很有用,而在
一个命令行中敲入这些模式显然极为繁琐。
     如果要查询存储代码 32L或2CC,可以使用( |)符号,意即“ |”符号两边之一或全部。
     可以使用任意多竖线符“ | ”                      ,例如要查看在系统中是否有帐号 l o u i s e 、 m a t t y 或 pauline ,
使用 who命令并管道输出至 egrep。
     还可以使用 ^ 符号排除字符串。如果要查看系统上的用户,但不包括 m a t t y 和 p a u l i n e ,方
法如下:
     如果要查询一个文件列表,包括 s h u t d o w n、s h u t d o w n s、 r e b o o t和r e b o o t s ,使用 e g r e p可容
易地实现。
                                                        65
                                         第8章 grep 家 族
 下载
8.6 小结
   希望大家已经理解了 g r e p的灵活性,它是一个很强大而流行的工具,像其他许多 U N I X工
具一样,已经被使用在 D O S 中。如果要通过文件快速查找字符串或模式, g r e p 是一个很好的
选择。简单地说, g r e p是s h e l l 编程中很重要的工具,在本书后面部分使用其他 U N I X工具和进
行变量替换时将发现这一点。


posted on 2009-09-16 22:29 memorygarden 阅读(272) 评论(0)  编辑 收藏 引用 所属分类: Linux

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理