grep的基本用法详解

 grep是linux上常用的一个文本处理工具之一。它有着强大的文本处理能力,学会它,可以让工作更有效率。

一、初识grep

  grep: Global search Regular Experssion and Print out line

  从名字上也可以直观的了解到它是基于正则表达式进行全局搜索,并把结果打印到屏幕上来。

  说白了,它就是根据用户指定的“模式(pattern)”来对文本进行过滤,并显示匹配到的行的文本搜索工具。


二、何为“模式”

  所谓模式,就是由一类字符书写,但是这些字符不表示字符本身字面的意义,而是表示控制或通配的功能。它还有一个高雅的名字,即正则表达式。


三、了解正则表达式

 1、基本的元字符

    .   匹配任意的字符

    *   匹配其前面的字符任意次数,0,1或多次

    \?  匹配其前面的字符0次或1次

    \+  匹配其前面的字符1次以上

  2、按字符匹配:

    .:   匹配任意单个字符

    []:   匹配指定集合中的任意单个字符

       常用的字符集合:

         [[:digit:]],[0-9]  表示0-9的任意数字

         [[:lower:]], [a-z]  表示26个小写英文字母

         [[:upper:]], [A-Z]  表示26个大写英文字母

         [[:alpha:]], [a-zA-Z] 表示所有英文字母

         [[:alnum:]], [[0-9a-zA-Z] 表示数字,所有英文字母

         [[:space:]]  表示空白字符

         [[:punct:]]  表示符号字符

    [^]:  匹配指定集合外的任意单个字符

  3、按匹配次数匹配:

   * : 匹配其前面任意字符任意次数

   \?: 匹配其前面的字符0次或1次

   \+: 匹配其前面的字符出现至少1次

   \{m\}: 匹配其前面的字符出现m次

   \{m,n\}: 匹配其前面的字符至少m次,至多n次

   .* : 常用组合,表示任意长度的任意字符

  4、实现位置锚定

   ^ : 写在模式的最左侧,表示锚定行首

   $ : 写在模式的最右侧,表示锚定行尾

   \<: 写在要查找的单词模式的左侧,做单词词首锚定

   \>: 写在要查找的单词模式的右侧,做单词词尾锚定

   ^$: 常用组合,表示空白行

   \<pattern\>: 匹配单词

  5、实现分组(只要功能可以用于实现后向引用)

    \(\): 在模式中,如果使用了分组,在某行文本检测中,如果\(\)匹配到了某内容,此内容可以在后面的模式中被引用。

    \# : 引用之前被\(\)所匹配到的内容,模式自左而右,引用第#个左括号以及其匹配右括号之间的模式匹配到的内容。


三、grep命令

  1、基本语法:  

     grep [OPTIONS] PATTERN [FILE…]

     常用选项:

       -i, –ignore-case  : 忽略字符大小写

       -o, –only-matching : 只显示被模式匹配到的内容

       -v, –invert-match : 反向选取,显示被模式匹配到的内容的相反内容

       -A #,–after-context=#: 显示被模式匹配到的行和此行之后的#行

       -B #,–before-context=#: 显示被模式匹配到的行和此行之前的#行

       -C #,–context=#: 显示被模式匹配到的行和此行前后的#行 

       -r, -R, –recursive: 递归查询,对目录下的子目录也会进行查询

       -E, –extended-regexp: 使用扩展正则表达式进行匹配,相当于egrep

       -F, –fixed-strings: 不使用正则表达式经行匹配,即忽略元字符的意义,相当于fgrep

       –color={never,always,auto}:可以设置颜色显示,可以进行别名,方便使用。例如:alias grep='grep –color=auto'


四、知识点练习

接下来我们以以下文本文件的内容来进行练习

blob.png

练习1:显示b出现3次以上的行

grep "b\{3,\}" test.txt

blob.png

练习2:统计文本文件中work|WORK出现的次数

grep -i -o "\<work\>" test.txt | wc -l

blob.png

练习3:显示所有包含符号的行

grep "[[:punct:]]" test.txt

blob.png

练习4:找出其中最后一个单词是由此前某单词加er构成的行。

grep "\(\<[[:alpha:]]\+\>\).*\1er" test.txt

blob.png


五、实际的应用

有了以上的知识储备,我们就可以用grep来进行一些基本的处理工作了。

1、在/etc/passwd上查找以/sbin/nolog结尾的行,即可以使用以/bin/nologin为结束的位置锚定进行选取

grep "/sbin/nologin$" /etc/passwd

QUAU2MM7V8]U3NFFHV[[CK2.png

2、在/etc/passwd上查找用户id和组id在500到1099之间的行

grep "\<1\?[05][0-9][0-9]\>" /etc/passwd

blob.png

3、查找当前系统上网卡驱动程序的名称

#显示pci设备中网卡的信息
#最前面的 “02:01.0” 就是设备在PCI总线上的代号,该代号在整个系统中是唯一的。(因为当前系统上有两块网卡,所以有两条信息)
[root@localhost tmp]# lspci | grep "Ethernet"
02:01.0 Ethernet controller: Intel Corporation 82545EM Gigabit Ethernet Controller (Copper) (rev 01)
02:05.0 Ethernet controller: Intel Corporation 82545EM Gigabit Ethernet Controller (Copper) (rev 01)

#sys目录是内核将设备信息映射出来的一个伪文件系统,所以我们查找到的那一行信息中drivers的子目录e1000即是网卡设备的驱动名称
[root@localhost tmp]# find /sys/bus/pci/drivers | grep "02:01.0"
/sys/bus/pci/drivers/e1000/0000:02:01.0

其实要做的事也就2步,然后我们可以把这些命令通过管道(|)来把命令连接起来,实现功能。

blob.png

原创文章,作者:封于修,如若转载,请注明出处:http://www.178linux.com/4746

评论列表(7条)

  • stanley
    stanley 2015-05-25 20:52

    才知道封于修不仅武功厉害,文章也相当牛了

    • 封于修
      封于修 2015-05-26 20:02

      @stanley谢谢stanley大哥,不过我还有好长的路需要努力…呵呵

  • 老鼠上了猫
    老鼠上了猫 2015-06-23 17:04

    2、在/etc/passwd上查找用户id和组id在500到1099之间的行
    grep “\” /etc/passwd
    这样取是有问题的,[05]是取0或5,那ID为600-1000间的用户是取不到的。
    中括号只能取一位数,我也不知道怎么取。

    • 封于修
      封于修 2015-06-26 23:03

      @老鼠上了猫你说的对,我没有考虑清楚。其实严谨的写grep -E “[5-9][0-9][0-9]|10[0-9][0-9]” /etc/passwd 应该才是对的。

    • 老鼠上了猫
      老鼠上了猫 2015-06-29 16:23

      @封于修你这是用户IP或组ID为500-1099:
      grep -e “[5-9][0-9][0-9]” -e “10[0-9][0-9]” /etc/passwd 这样也可以
      如果需满足用户IP和组IP为500-1099的话,只用grep想不出怎么匹配,用awk就比较简单了:
      awk -F: ‘$3>=500 && $4<=1099 {print $0}' /etc/passwd

    • 封于修
      封于修 2015-06-29 19:21

      @老鼠上了猫条件式的判断选取用awk是会更好。
      grep其实也是可以的,就是会很麻烦。
      grep -E “[^:]+:[^:]+:([5-9][0-9][0-9]|10[0-9][0-9]):([5-9][0-9][0-9]|10[0-9][0-9]):.*” /etc/passwd
      我试了一下,这样写也是可以匹配得到的。或许会有更简便的写法,只能等大神解答了。

    • 老鼠上了猫
      老鼠上了猫 2015-06-29 19:30

      @封于修整行匹配肯定没问题的,这也是一思路,赞!