美文网首页
linux三剑客之grep

linux三剑客之grep

作者: piziyang12138 | 来源:发表于2018-09-06 16:42 被阅读0次

    grep擅长查找,awk擅长分析(select),sed擅长批量编辑行

    常用的grep选项有:
    -c 只输出匹配行的计数。
    -i 不区分大小写(只适用于单字符)。
    -h 查询多文件时不显示文件名。
    -l 查询多文件时只输出包含匹配字符的文件名。
    -n 显示匹配行及行号。
    -s 不显示不存在或无匹配文本的错误信息。
    -v 显示不包含匹配文本的所有行。

    我们经常会这样grep文件:

    
    root@nm3:/  \# cat /var/run/dmesg.boot | grep CPU:
    
    CPU:  Intel Core(TM)2  Quad CPU    Q9550@  2.83GHz  (2833.07-MHz K8-class  CPU)
    
    

    还可以这样做:

    root@nm3:/  \# grep CPU: /var/run/dmesg.boot
    
    CPU:  Intel Core(TM)2  Quad CPU    Q9550@  2.83GHz  (2833.07-MHz K8-class  CPU)
    
    

    这样也是可以的(虽然我很讨厌这种操作方式):

    
    root@nm3:/  \# </var/run/dmesg.boot grep CPU:
    
    CPU:  Intel Core(TM)2  Quad CPU    Q9550@  2.83GHz  (2833.07-MHz K8-class  CPU)
    
    

    你肯定会遇到这样的场景:统计文件中带有某些关键字的行出现的次数。grep+wc可以帮到你:

    root@nm3:/  \# grep WARNING /var/run/dmesg.boot | wc -l
    
    

    条条大路通罗马,下面是另一条路:

    
    root@nm3:/  \# grep WARNING /var/run/dmesg.boot -c
    
    

    下面我们新建一个测试用的文档:

    
    root@nm3:/  \# grep ".*" test.txt
    
    one two three
    
    seven eight one eight three
    
    thirteen fourteen fifteen
    
    sixteen seventeen eighteen seven
    
    sixteen seventeen eighteen
    
    twenty seven
    
    one  504  one
    
    one  503  one
    
    one 504 one
    
    one 504  one
    
    #comment UP
    
    twentyseven
    
    #comment down
    
    twenty1
    
    twenty3
    
    twenty5
    
    twenty7
    
    

    继续grep的搜索之旅。

    -w选项指定要搜索的单词:

    
    root@nm3:/  grep -w 'seven' test.txt
    
    seven eight one eight three
    
    sixteen seventeen eighteen seven
    
    twenty seven
    
    

    如果想搜以特定字符开头(结尾)的单词,可以这样:

    
    root@nm3:/  \# grep '\<seven' test.txt
    
    seven eight one eight three
    
    sixteen seventeen eighteen seven
    
    sixteen seventeen eighteen
    
    twenty seven
    
    root@nm3:/  \# grep 'seven\>' test.txt
    
    seven eight one eight three
    
    sixteen seventeen eighteen seven
    
    twenty seven
    
    twentyseven
    
    

    如果想搜以特定字符开头(结尾)的行,可以这样:

    root@nm3:/  \# grep '^seven' test.txt
    
    seven eight one eight three
    
    root@nm3:/  \# grep 'seven$' test.txt
    
    sixteen seventeen eighteen seven
    
    twenty seven
    
    twentyseven
    
    root@nm3:/  #
    
    

    想要显示目标行的上下文吗?

    
    root@nm3:/  \# grep -C 1 twentyseven test.txt
    
    #comment UP
    
    twentyseven
    
    #comment down
    
    

    到底是显示上文还是下文?

    
    root@nm3:/  \# grep -A 1 twentyseven test.txt
    
    twentyseven
    
    #comment down
    
    root@nm3:/  \# grep -B 1 twentyseven test.txt
    
    #comment UP
    
    twentyseven
    
    

    我们还可以这样玩grep:

    
    root@nm3:/  \# grep "twenty[1-4]" test.txt
    
    twenty1
    
    twenty3
    
    
    
    root@nm3:/  \# grep "twenty[^1-4]" test.txt
    
    twenty seven
    
    twentyseven
    
    twenty5
    
    twenty7
    
    

    grep是个强大的指令,除上述列举的之外,它还支持许多限定符、通配符以及正则表达式。下面是一些例子:

    
    root@nm3:/  \# cat /etc/resolv.conf
    
    #options edns0
    
    #nameserver 127.0.0.1
    
    nameserver  8.8.8.8
    
    nameserver  77.88.8.8
    
    nameserver  8.8.4.4
    
    

    只获取IP地址相关的行:

    root@nm3:/  \# grep -E "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" /etc/resolv.conf
    
    #nameserver 127.0.0.1
    
    nameserver  8.8.8.8
    
    nameserver  77.88.8.8
    
    nameserver  8.8.4.4
    
    

    上面的方法可行,但下面这种方法更好:

    root@nm3:/  \# grep -E '\b[0-9]{1,3}(\.[0-9]{1,3}){3}\b' /etc/resolv.conf
    
    #nameserver 127.0.0.1
    
    nameserver  8.8.8.8
    
    nameserver  77.88.8.8
    
    nameserver  8.8.4.4
    
    

    希望去掉注释行?

    
    root@nm3:/  \# grep -E '\b[0-9]{1,3}(\.[0-9]{1,3}){3}\b' /etc/resolv.conf | grep -v '#'
    
    nameserver  8.8.8.8
    
    nameserver  77.88.8.8
    
    nameserver  8.8.4.4
    
    

    只要IP:

    
    root@nm3:/  \# grep -oE '\b[0-9]{1,3}(\.[0-9]{1,3}){3}\b' /etc/resolv.conf | grep -v '#'
    
    127.0.0.1
    
    8.8.8.8
    
    77.88.8.8
    
    8.8.4.4
    
    

    哎呀,被注释掉的127.0.0.1又回来了,这是指令执行顺序不当导致的,怎么破?

    
    root@nm3:/  \# grep -v '#' /etc/resolv.conf | grep -oE '\b[0-9]{1,3}(\.[0-9]{1,3}){3}\b'
    
    8.8.8.8
    
    77.88.8.8
    
    8.8.4.4
    
    

    下面看下-v(反向查找)选项的使用。

    假设要执行指令“ps –afx | grep ttyv ”:

    root@nm3:/  \# ps -afx | grep ttyv
    
    1269  v1  Is+ 0:00.00  /usr/libexec/getty Pc ttyv1
    
    1270  v2  Is+ 0:00.00  /usr/libexec/getty Pc ttyv2
    
    1271  v3  Is+ 0:00.00  /usr/libexec/getty Pc ttyv3
    
    1272  v4  Is+ 0:00.00  /usr/libexec/getty Pc ttyv4
    
    1273  v5  Is+ 0:00.00  /usr/libexec/getty Pc ttyv5
    
    1274  v6  Is+ 0:00.00  /usr/libexec/getty Pc ttyv6
    
    1275  v7  Is+ 0:00.00  /usr/libexec/getty Pc ttyv7
    
    487982S+0:00.00  grep  ttyv
    
    

    OK,但是我们不需要“48798 2 S+ 0:00.00 grep ttyv”一行,使用-v:

    
    root@nm3:/  \# ps -afx | grep ttyv | grep -v grep
    
    1269  v1  Is+ 0:00.00  /usr/libexec/getty Pc ttyv1
    
    1270  v2  Is+ 0:00.00  /usr/libexec/getty Pc ttyv2
    
    1271  v3  Is+ 0:00.00  /usr/libexec/getty Pc ttyv3
    
    1272  v4  Is+ 0:00.00  /usr/libexec/getty Pc ttyv4
    
    1273  v5  Is+ 0:00.00  /usr/libexec/getty Pc ttyv5
    
    1274  v6  Is+ 0:00.00  /usr/libexec/getty Pc ttyv6
    
    1275  v7  Is+ 0:00.00  /usr/libexec/getty Pc ttyv7
    
    

    别忘了| (或)符号:

    root@nm3:/  \# vmstat -z | grep -E "(sock|ITEM)"
    
    ITEM SIZE  LIMIT USED FREE      REQ FAIL SLEEP
    
    socket: 696,  130295,30,65, 43764, 0, 0
    
    

    殊途同归:

    root@nm3:/  \# vmstat -z | grep "sock\|ITEM"
    
    ITEM SIZE  LIMIT USED FREE      REQ FAIL SLEEP
    
    socket: 696,  130295,30,65, 43825, 0, 0
    
    

    许多人都会在grep中用正则表达式,但你仍会忘了用POSIX字符集,即便它们也非常有用。

    POSIX:

    [[:alpha:]]  Any alphabetical character,  regardless of case
    
    [[:digit:]]  Any numerical character
    
    [[:alnum:]]  Any alphabetical or  numerical character
    
    [[:blank:]]  Space or  tab characters
    
    [[:xdigit:]]  Hexadecimal characters;  any number or  A–F  or  a–f
    
    [[:punct:]]  Any punctuation symbol
    
    [[:print:]]  Any printable character  (not  control characters)
    
    [[:space:]]  Any whitespace character
    
    [[:graph:]]  Exclude whitespace characters
    
    [[:upper:]]  Any uppercase letter
    
    [[:lower:]]  Any lowercase letter
    
    [[:cntrl:]]  Control characters
    
    

    找有大写字母的行:

    root@nm3:/  \# grep "[[:upper:]]" test.txt
    
    #comment UP
    
    

    搜索结构不够醒目?高亮显示:

    image.png

    更多的grep小窍门。第一个稍显专业,我已经15年没用过了。

    选择包含six,seven或者eight的行,很简单:

    
    root@nm3:/  \# grep -E "(six|seven|eight)" test.txt
    
    seven eight one eight three
    
    sixteen seventeen eighteen seven
    
    sixteen seventeen eighteen
    
    twenty seven
    
    twentyseven
    
    

    那么现在只选择包含six,seven或者eight若干次的行。这种用法叫回溯引用:

    root@nm3:/  \# grep -E "(six|seven|eight).*\1" test.txt
    
    seven eight one eight three
    
    sixteen seventeen eighteen seven
    
    

    我漏讲什么了吗?grep具备递归搜索文件/目录功能。如果我们想在源码目录中搜索允许Intel使用外部SFPs的代码,但是又没清楚完整地记着函数名allow_unsupported_stp和unsupported_allow_sfp。肿么办?这正是grep的菜:

    
    root@nm3:/  \# grep -rni allow /usr/src/sys/dev/ | grep unsupp
    
    /usr/src/sys/dev/ixgbe/README:75:of unsupported modules by setting the static variable  'allow\_unsupported\_sfp'
    
    /usr/src/sys/dev/ixgbe/ixgbe.c:322:static int  allow\_unsupported\_sfp  =  TRUE;
    
    /usr/src/sys/dev/ixgbe/ixgbe.c:323:TUNABLE_INT("hw.ixgbe.unsupported_sfp",  &allow\_unsupported\_sfp);
    
    /usr/src/sys/dev/ixgbe/ixgbe.c:542: hw->allow\_unsupported\_sfp  =  allow\_unsupported\_sfp;
    
    /usr/src/sys/dev/ixgbe/ixgbe_type.h:3249: bool  allow\_unsupported\_sfp;
    
    /usr/src/sys/dev/ixgbe/ixgbe_phy.c:1228:if  (hw->allow\_unsupported\_sfp  ==  TRUE)  {
    
    

    希望你还没晕,因为这些grep用法只是grep的冰山一角呢!

    最后祝大家 Happy grepping!

    相关文章

      网友评论

          本文标题:linux三剑客之grep

          本文链接:https://www.haomeiwen.com/subject/ubixgftx.html