zoukankan      html  css  js  c++  java
  • 每日一个Linux 命令-Grep

    Grep

    grep (global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。Unix的grep家族包括grep、egrep和fgrep。egrep和fgrep的命令只跟grep有很小不同。egrep是grep的扩展,支持更多的re元字符, fgrep就是fixed grep或fast grep,它们把所有的字母都看作单词,也就是说,正则表达式中的元字符表示回其自身的字面意义,不再特殊。Linux使用GNU版本的grep。它功能更强,可以通过-G、-E、-F命令行选项来使用egrep和fgrep的功能。

    grep的工作方式是这样的,它在一个或多个文件中搜索字符串模板。如果模板包括空格,则必须被引用,模板后的所有字符串被看作文件名。搜索的结果被送到屏幕,不影响原文件内容。

    grep可用于shell脚本,因为grep通过返回一个状态值来说明搜索的状态,如果模板搜索成功,则返回0,如果搜索不成功,则返回1,如果搜索的文件不存在,则返回2。我们利用这些返回值就可进行一些自动化的文本处理工作。

    语法

    grep [-abcEFGhHilLnqrsvVwxy][-A<显示列数>][-B<显示列数>][-C<显示列数>][-d<进行动作>][-e<范本样式>][-f<范本文件>][--help][范本样式][文件或目录...]

    匹配模式选择:
     -E, --extended-regexp     扩展正则表达式egrep
     -F, --fixed-strings       一个换行符分隔的字符串的集合fgrep
     -G, --basic-regexp        基本正则
     -P, --perl-regexp         调用的perl正则
     -e, --regexp=PATTERN      后面根正则模式,默认无
     -f, --file=FILE           从文件中获得匹配模式
     -i, --ignore-case         不区分大小写
     -w, --word-regexp         匹配整个单词
     -x, --line-regexp         匹配整行
     -z, --null-data           一个 0 字节的数据行,但不是空行
    
    杂项:
     -s, --no-messages         不显示错误信息
     -v, --invert-match        显示不匹配的行
     -V, --version             显示版本号
     --help                    显示帮助信息
     --mmap                use memory-mapped input if possible
    
    输入控制:
     -m, --max-count=NUM       匹配的最大数
     -b, --byte-offset         打印匹配行前面打印该行所在的块号码。
     -n, --line-number         显示的加上匹配所在的行号
     --line-buffered           刷新输出每一行
     -H, --with-filename       当搜索多个文件时,显示匹配文件名前缀
     -h, --no-filename         当搜索多个文件时,不显示匹配文件名前缀
     --label=LABEL            print LABEL as filename for standard input
     -o, --only-matching       只显示一行中匹配PATTERN 的部分
     -q, --quiet, --silent      不显示任何东西
     --binary-files=TYPE   假定二进制文件的TYPE 类型;
                                          TYPE 可以是`binary', `text', 或`without-match'
     -a, --text                匹配二进制的东西
     -I                        不匹配二进制的东西
     -d, --directories=ACTION  目录操作,读取,递归,跳过
     -D, --devices=ACTION      设置对设备,FIFO,管道的操作,读取,跳过
     -R, -r, --recursive       递归调用
     --include=PATTERN     只查找匹配FILE_PATTERN 的文件
     --exclude=PATTERN     跳过匹配FILE_PATTERN 的文件和目录
     --exclude-from=FILE   跳过所有除FILE 以外的文件
     -L, --files-without-match 匹配多个文件时,显示不匹配的文件名
     -l, --files-with-matches  匹配多个文件时,显示匹配的文件名
     -c, --count               显示匹配的行数
     -Z, --null                在FILE 文件最后打印空字符
    
    文件控制:
     -B, --before-context=NUM  打印匹配本身以及前面的几个行由NUM控制
     -A, --after-context=NUM   打印匹配本身以及随后的几个行由NUM控制
     -C, --context=NUM         打印匹配本身以及随后,前面的几个行由NUM控制
     -NUM                      根-C的用法一样的
     --color[=WHEN],
     --colour[=WHEN]       使用标志高亮匹配字串;
     
     -U, --binary               使用标志高亮匹配字串;
     -u, --unix-byte-offsets   当CR 字符不存在,报告字节偏移(MSDOS 模式)
    参数

    实例

    1、在当前目录中,查找后缀有 file 字样的文件中包含 test 字符串的文件,并打印出该字符串的行。此时,可以使用如下命令:

    [root@localhost test]# grep test test* #查找前缀有“test”的文件包含“test”字符串的文件 
    testfile1:This a Linux testfile
    ! #列出testfile1 文件中包含test字符的行 testfile_2:This is a linux testfile! #列出testfile_2 文件中包含test字符的行 testfile_2:Linux test #列出testfile_2 文件中包含test字符的行

    2、以递归的方式查找符合条件的文件。例如,查找指定目录/etc/acpi 及其子目录(如果存在子目录的话)下所有文件中包含字符串"update"的文件,并打印出该字符串所在行的内容,使用的命令为:

    [root@localhost test]# grep -r update /etc/acpi #以递归的方式查找“etc/acpi”  
    
    #下包含“update”的文件
    /etc/acpi/ac.d/85-anacron.sh:# (Things like the slocate updatedb cause a lot of IO.) Rather than /etc/acpi/resume.d/85-anacron.sh:# (Things like the slocate updatedb cause a lot of IO.) Rather than /etc/acpi/events/thinkpad-cmos:action=/usr/sbin/thinkpad-keys--update

    3、反向查找。前面各个例子是查找并打印出符合条件的行,通过"-v"参数可以打印出不符合条件行的内容。查找文件名中包含 test 的文件中不包含test 的行,此时,使用的命令为:

    [root@localhost test]# grep -v test* #查找文件名中包含test 的文件中不包含test 的行  
    
    testfile1:helLinux
    ! testfile1:Linis a free Unix-type operating system. testfile1:Lin testfile_1:HELLO LINUX! testfile_1:LINUX IS A FREE UNIX-TYPE OPTERATING SYSTEM. testfile_1:THIS IS A LINUX TESTFILE! testfile_2:HELLO LINUX! testfile_2:Linux is a free unix-type opterating system.

    4、匹配以HELLO开头或者以test开头的行,注意反斜杠,根上面一个例子一样,-e默认是省去的

    [root@localhost test]# cat test |grep -e '^(HELLO|test)'  

    HELLO LINUX!
    test Linux !

    5、匹配以sui开头,只含有字母

    [root@localhost test]# echo 'suixinnan' |grep '^sui[a-z]*$'  
    
    suixinnan

    新建测试文件

    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/bin/false,aaa,bbbb,cccc,aaaaaa
    DADddd:x:2:2:daemon:/sbin:/bin/false
    mail:x:8:12:mail:/var/spool/mail:/bin/false
    ftp:x:14:11:ftp:/home/ftp:/bin/false
    &nobody:$:99:99:nobody:/:/bin/false
    suixinnan:x:1000:100:,,,:/home/suixinnan:/bin/bash
    http:x:33:33::/srv/http:/bin/false
    dbus:x:81:81:System message bus:/:/bin/false
    hal:x:82:82:HAL daemon:/:/bin/false
    mysql:x:89:89::/var/lib/mysql:/bin/false
    aaa:x:1001:1001::/home/aaa:/bin/bash
    test:x:1003:1003::/home/test:/bin/bash
    policykit:x:102:1005:Po

    a,匹配以bin开头的行,用的egrep,在这里可以换成-F,-G

    [root@localhost test]# cat test |grep -E '^bin'  
    
    bin:x:1:1:bin:/bin:/bin/false,aaa,bbbb,cccc,aaaaaa  

    b,在匹配的行前面加上该行在文件中,或者输出中所在的行号

    [root@localhost test]# cat test|grep -n suixin
    
    7:suixinnan:x:1000:100:,,,:/home/suixinnan:/bin/bash  

    c,不匹配以bin开头的行,并显示行号

    [root@localhost test]# cat test|grep -nv '^bin'  
    
    root:x:0:0:root:/root:/bin/bash
    DADddd:x:2:2:daemon:/sbin:/bin/false
    mail:x:8:12:mail:/var/spool/mail:/bin/false
    ftp:x:14:11:ftp:/home/ftp:/bin/false
    &nobody:$:99:99:nobody:/:/bin/false
    suixinnan:x:1000:100:,,,:/home/suixinnan:/bin/bash
    http:x:33:33::/srv/http:/bin/false
    dbus:x:81:81:System message bus:/:/bin/false
    hal:x:82:82:HAL daemon:/:/bin/false
    mysql:x:89:89::/var/lib/mysql:/bin/false
    aaa:x:1001:1001::/home/aaa:/bin/bash
    test:x:1003:1003::/home/test:/bin/bash
    policykit:x:102:1005:Po

    d,显示匹配的个数,不显示内容

    [root@localhost test]#  cat test|grep -c sui  
    
    1  

    e,匹配system,没有加-i没有匹配到东西。

    [root@localhost test]# grep  system test  
    [root@localhost test]# grep -ni  system test  
    
    9:dbus:x:81:81:System message bus:/:/bin/false  

    f,匹配sui没有匹配到东西,匹配suixinnan能匹配到,因为在test文件中,有suixinnan这个单词

    [root@localhost test]#  cat test|grep -w sui  
    [root@localhost test]# cat test|grep -w suixinnan 
    
    suixinnan:x:1000:100:,,,:/home/suixinnan:/bin/bash  

    g,在这里-x后面东西,和输出中的整行相同时,才会输出

    [root@localhost test]# echo "aaaaaa" |grep -x aaa  
    [root@localhost test]# echo "aaaa" |grep -x aaaa  
    
    aaaa  

    h,最多只匹配一次,如果把-m 1去掉的话,会有多个(前提test 文件中有多个)

    [root@localhost test]# cat test |grep -m 1 suixin 
     
    suixinnan:x:1000:100:,,,:/home/suixinnan:/bin/bash  

    i,匹配行的前面显示块号,这个块号是干什么的,不知道,有谁知道可否告诉我一下

    [root@localhost test]# cat test |grep -b suixin
     
    241:suixinnan:x:1000:100:,,,:/home/suixinnan:/bin/bash  
    
    

    j,多文件匹配时,在匹配的行前面加上文件名

    [root@localhost test]# grep -H 'root' test test2 testbak  
    
    test:root:x:0:0:root:/root:/bin/bash  
    test2:root  
    testbak:root:x:0:0:root:/root:/bin/bash 

    k,多文件匹配时,在匹配的行前面不加上文件名

    [root@localhost test]# grep -h 'root' test test2 testbak  
    
    root:x:0:0:root:/root:/bin/bash  
    root  
    root:x:0:0:root:/root:/bin/bash  

    l,多文件匹配时,显示匹配文件的文件名

    [root@localhost test]# grep -l 'root' test test2 testbak DAta  
    
    test  
    test2  
    testbak  

    m,没有-o时,有一行匹配,这一行里面有3个root,加上-o后,这个3个root就出来了

    [root@localhost test]# grep  'root' test 
     
    root:x:0:0:root:/root:/bin/bash
      
    [root@localhost test]# grep -o 'root' test 
     
    root  
    root  
    root  

    n,递归显示匹配的内容,在test目录下面建个mytest目录,copy test目录下面的test文件到mytest下面,能看到上面的结果

    [root@localhost test]# grep test -R /tmp/test/mytest
      
    /tmp/test/mytest/test:test:x:1003:1003::/home/test:/bin/bash  
    /tmp/test/mytest/test:@zhangying:*:1004:1004::/home/test:/bin/bash  

    o,显示匹配root后面的3行

    [root@localhost test]# cat test |grep -A 3 root  
    root:x:
    0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/bin/false,aaa,bbbb,cccc,aaaaaa daemon:x:2:2:daemon:/sbin:/bin/false mail:x:8:12:mail:/var/spool/mail:/bin/false

    场景:

    系统报警显示了时间,但是日志文件太大无法直接 cat 查看。(查询含有特定文本的文件,并拿到这些文本所在的行)

    解决:

    [root@localhost test]#grep -n '2020-08-24 00:01:11' *.log

    从根目录开始查找所有扩展名为 .log 的文本文件,并找出包含 "ERROR" 的行:

    [root@localhost test]# find / -type f -name "*.log" | xargs grep "ERROR"

    从当前目录开始查找所有扩展名为 .in 的文本文件,并找出包含 "thermcontact" 的行:

    [root@localhost test]#find . -name "*.in" | xargs grep "thermcontact"
    递归从所有文件中查询匹配的内容,文件名可不同
    [root@localhost test]# grep -R C1079651000621  *   
    
    20200727/503/20200701000104001317.xml:            C1079651000621
    20200727/503/20200701000104001317.xml:            C1079651000621
    20200727/503/20200701000104001333.xml:            C1079651000621
    有一点要注意,您必需提供一个文件过滤方式(搜索全部文件的话用 *)。如果您忘了,’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 "abc|xyz" testfile 表示过滤包含abc或xyz的行
        grep pattern1 files | grep pattern2 :显示既匹配 pattern1 又匹配 pattern2 的行。
        grep -n pattern files 即可显示行号信息
        grep -c pattern files 即可查找总行数
        还有些用于搜索的特殊符号:< 和 > 分别标注单词的开始与结尾。
        例如:
        grep man * 会匹配 ‘Batman’、’manic’、’man’等,
        grep ‘<man’ * 匹配’manic’和’man’,但不是’Batman’,
        grep ‘<man>’ 只匹配’man’,而不是’Batman’或’manic’等其他的字符串。
        ‘^’: 指匹配的字符串在行首,
        ‘$’: 指匹配的字符串在行 尾,
        
        用grep查找结构体 grep -R "struct task_struct {" /usr/src 加-n可以显示行号PS1=$ 进入到家目录在.bashrc    中
     
     
     
     
  • 相关阅读:
    LeetCode 230. 二叉搜索树中第K小的元素(Kth Smallest Element in a BST)
    LeetCode 216. 组合总和 III(Combination Sum III)
    LeetCode 179. 最大数(Largest Number)
    LeetCode 199. 二叉树的右视图(Binary Tree Right Side View)
    LeetCode 114. 二叉树展开为链表(Flatten Binary Tree to Linked List)
    LeetCode 106. 从中序与后序遍历序列构造二叉树(Construct Binary Tree from Inorder and Postorder Traversal)
    指针变量、普通变量、内存和地址的全面对比
    MiZ702学习笔记8——让MiZ702变身PC的方法
    你可能不知道的,定义,声明,初始化
    原创zynq文章整理(MiZ702教程+例程)
  • 原文地址:https://www.cnblogs.com/suixinnan/p/13667432.html
Copyright © 2011-2022 走看看