linux命令之-grep文本搜索工具

linux命令之-grep文本搜索工具

1、grep命令详解

1.1、命令介绍

  • Global search REgular expression and Print out the line. 文本搜索工具,根据用户指定的文本模式(正则表达元字符以及正常字符组合而成)对目标文件进行逐行搜索,显示能匹配到的行;linux使用GNU版本的grep。它功能更强,可以通过-G、-E、-F命令行选项来使用egrep和fgrep的功能。
    image_1dlhnaq1rrkrom49l66k0rd29.png-713.2kB

1.2、正则表达式:REGular EXPression REGEXP

  • 是由元字符及正常字符所书写的模式,其中的元字符不表示字符本身的意义,而是用于表达控制或通配等功能;
  • 基本正则表达式命令: grep

    提示:fgrep: fast, 不支持使用正则表达式

1.2.1、基本正则表达式元字符

提示:匹配数字别忘了中括号外面还有一个中括号。

  • 字符匹配:
    . :匹配任意单个字符
    []: 匹配指定范围内的任意单个字符
    [^]: 匹配指定范围外的任意单个字符
    [0-9], [[:digit:]], [^0-9], [^[:digit:]]
    [a-z], [[:lower:]]
    [A-Z], [[:upper:]]
    [[:space:]]
    [[:punct:]]
    [0-9a-zA-Z], [[:alnum:]]
    [a-zA-Z], [[:alpha:]]
    [:alnum:] 字母数字 [a-z A-Z 0-9]
    [:alpha:] 字母 [a-z A-Z]
    [:blank:] 空格或制表键
    [:cntrl:] 任何控制字符
    [:digit:] 数字 [0-9]
    [:graph:] 任何可视字符(无空格)
    [:lower:] 小写 [a-z]
    [:print:] 非控制字符
    [:punct:] 标点字符
    [:space:] 空格
    [:upper:] 大写 [A-Z]
    [:xdigit:] 十六进制数字 [0-9 a-f A-F]

  • 次数匹配:在期望匹配字符后面提供一个控制符,用于表达匹配其前面字符指定的次数
    * : 任意长度,表示0次、1次或多次;

    1
    2
    3
    例子:"ab*c"
    abbc, ac
    abb,

    .*: 任意长度的任意字符

    提示:工作于贪婪模式

    \?:0次或1次;表示其左侧字符可有可无

    1
    2
    3
    例子:"ab\?c"
    abbc,
    ac, abc

    \+: 1次或多次;表示其左侧字符至少出现1次;

    1
    2
    3
    例子:"ab\+c"
    ac,
    abc, abbbbc

    \{m\}:m次;表示其左侧字符精确出现m次;

    1
    2
    3
    例子:ab\{2\}c
    ac, abc, abbbc
    abbc

    \{m,n\}:至少m次,至多n次;

    1
    2
    3
    例子:ab\{0,3\}c
    ac, abbbc,
    abbbbbc

    \{0,n\}:至多n次;
    \{m,\}:至少m次;

  • 位置锚定:
    ^:锚定行首

    1
    例子:^PATTERN

    $:锚定行尾

    1
    列子:PATTERN$

    ^PATTERN$:用模式来匹配整行;

    1
    列子:grep "^[[:space:]]*$" /etc/rc.d/rc.sysinit

    ^$:匹配空白行;

  • 单词锚定:由非特殊字符组成的连续的字符串
    \< :锚定词首,也可用\b

    1
    2
    \<PATTERN, 或\bPATTERN
    grep "\<sh" /etc/passwd

    \> :锚定词尾,也可以用\b

    1
    PATTERN\>, 或PATTERN\b

    \<PATTERN\>:匹配PATTERN能匹配到的整个单词

    1
    ifconfig | grep "\<[0-9]\{2\}\>"
  • 分组:

    注意:分组中的模式,在某次的具体匹配过程中所匹配到的字符,可以被grep记忆(保存于内置的变量中,这些变量是\1, \2, …),因此,还可以被引用;
    \1: 引用,模式中自左而右,由第一个左括号以及与之对应的右括号中的模式所匹配到的内容;
    \1: 引用 ,模式中自左右,由第二个左括号以及与之对应的右括号中的模式所匹配到的内容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    例子:
    “\(a.b\).*\1"
    amb hello anb

    "\(l..e\).*\1"
    He like his lover.
    He like his liker.
    She love her lover.
    She love her liker.

    \(.*\)\.mp3.*\1\.wvm
    play.php?a.mp3?search?a.wmv
    play.php?where.mp3?hello?when.wmv

1.3、扩展的正则表达式

  • 扩展正则表达式: grep -E, egrep

1.3.1、扩展正则表达式元字符

  • 字符匹配:
    . :匹配任意单个字符
    []: 匹配指定范围内的任意单个字符
    [^]: 匹配指定范围外的任意单个字符
    [0-9], [[:digit:]], [^0-9], [^[:digit:]]
    [a-z], [[:lower:]]
    [A-Z], [[:upper:]]
    [[:space:]]
    [[:punct:]]
    [0-9a-zA-Z], [[:alnum:]]
    [a-zA-Z], [[:alpha:]]
    [:alnum:] 字母数字 [a-z A-Z 0-9]
    [:alpha:] 字母 [a-z A-Z]
    [:blank:] 空格或制表键
    [:cntrl:] 任何控制字符
    [:digit:] 数字 [0-9]
    [:graph:] 任何可视字符(无空格)
    [:lower:] 小写 [a-z]
    [:print:] 非控制字符
    [:punct:] 标点字符
    [:space:] 空格
    [:upper:] 大写 [A-Z]
    [:xdigit:] 十六进制数字 [0-9 a-f A-F]

  • 次数匹配:
    *: 任意次
    ?:0或1次
    +: 至少1次
    {m}:精确匹配m次;
    {m,n}:至少m次,至多次;
    {m,}:至少m次;
    {0,n}:至多次;

  • 位置锚定:
    ^
    $
    \<, \b
    \>, \b

  • 分组:
    ()
    引用:\1,\2,...

  • 或者:
    a|b:a或者b

    或者两侧的所有内容;
    
  • 命令:
    grep -E PATTERN FILE...
    egrep PATTERN FILE...

2、grep命令常用语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
grep命令:
grep [OPTIONS] PATTERN [FILE...]
--color[=WHEN], --colour[=WHEN]
auto
always
never
例子:grep --color=auto "root" /etc/passwd

-o: 只显示被模式匹配到的内容
-i: ignore case,不区分字符大小写
-v: 显示不能够被模式匹配到的行
-E:使用扩展的正则表达式
-l:匹配多个文件时,显示匹配的文件名
-L:匹配多个文件时,显示不匹配的文件名
-a:匹配二进制的文件
-I:不匹配二进制的文件
-A #:后几行
-B #:前几行
-C #:前后几行

3、grep命令练习

3.1、普通正则表达式练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1、显示/proc/meminfo文件中以大写或小写S开头的行;用两种方式;
# grep "^[sS]" /proc/meminfo

2、显示/etc/passwd文件中其默认shell为非/sbin/nologin的用户;
# grep -v "/sbin/nologin$" /etc/passwd | cut -d: -f1

3、显示/etc/passwd文件中其默认shell为/bin/bash的用户;
# grep "/bin/bash$" /etc/passwd | cut -d: -f1

4、找出/etc/passwd文件中的一位数或两位数;
# grep "\<[0-9]\{1,2\}\>" /etc/passwd

5、显示/boot/grub/grub.conf中以至少一个空白字符开头的行;
# grep "^[[:space:]]\+" /boot/grub/grub.conf

6、显示/etc/rc.d/rc.sysinit文件中以#开头,后面跟至少一个空白字符,而后又有至少一个非空白字符的行;
# grep "^#[[:space:]]\+[^[:space:]]\+" /etc/rc.d/rc.sysinit

7、打出netstat -tan命令执行结果中以‘LISTEN’,后或跟空白字符结尾的行;
# netstat -tan | grep "LISTEN[[:space:]]*$"

8、添加用户bash, testbash, basher, nologin (此一个用户的shell为/sbin/nologin),而后找出当前系统上其用户名和默认shell相同的用户的信息;
# grep "^\([[:alnum:]]\+\>\).*\1$" /etc/passwd

3.1、扩展正则表达式练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
1、显示/proc/meminfo文件中以大写或小写S开头的行;用三种方式;
# grep -E "^[sS]" /proc/meminfo
# grep -E "^(s|S)" /proc/meminfo
# egrep -i "^s" /proc/meminfo

2、显示/etc/passwd文件中其默认shell为非/sbin/nologin的用户;
# egrep -v "/sbin/nologin$" /etc/passwd | cut -d: -f1

3、显示/etc/passwd文件中其默认shell为/bin/bash的用户;
# egrep "/bin/bash$" /etc/passwd | cut -d: -f1

4、找出/etc/passwd文件中的一位数或两位数;
# egrep --color=auto "\<[0-9]{1,2}\>" /etc/passwd

5、显示/boot/grub/grub.conf中以至少一个空白字符开头的行;
# egrep "^[[:space:]]+" /boot/grub/grub.conf

6、显示/etc/rc.d/rc.sysinit文件中以#开头,后面跟至少一个空白字符,而后又有至少一个非空白字符的行;
# egrep "^#[[:space:]]+[^[:space:]]+" /etc/rc.d/rc.sysinit

7、打出netstat -tan命令执行结果中以‘LISTEN’,后或跟空白字符结尾的行;
# netstat -tan | egrep "LISTEN[[:space:]]*$"

8、添加用户bash, testbash, basher, nologin (此一个用户的shell为/sbin/nologin),而后找出当前系统上其用户名和默认shell相同的用户的信息;
# egrep "^([[:alnum:]]+\>).*\1$" /etc/passwd

9、显示当前系统上root、fedora或user1用户的默认shell;
# grep -E "^(root|fedora|user1)\>" /etc/passwd | cut -d: -f7

10、找出/etc/rc.d/init.d/functions文件中某单词后面跟一组小括号的行,形如:hello();
# grep -o -E "\<[[:alnum:]]+\>\(\)" /etc/rc.d/init.d/functions

11、使用echo命令输出一个绝对路径,使用grep取出其基名;
扩展:取出其路径名
# echo /etc/rc.d/init.d/functions | grep -o -E "[[:alnum:]]+/?$" | cut -d/ -f1

12、找出ifconfig命令结果中的1-255之间数字;
# ifconfig | grep -E "\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>"

13、挑战题:写一个模式,能匹配合理的IP地址;
1.0.0.1 -- 239.255.255.255

14、挑战题:写一个模式,能匹配出所有的邮件地址;
-------------本文结束感谢您的阅读-------------
LiGuanCheng wechat
如有问题,请与我微信交流或通过右下角“daovoice”与我联系~。
请我喝一杯咖啡~