zoukankan      html  css  js  c++  java
  • 文本处理三剑客之 grep

    grep简介

      grep(Global search REgular expression and Print out the line)是Linux上的文本处理三剑客之一,另外两个是sed和awk.

      grep是文本搜索工具,根据用户指定的pattern(由文本字符及正则表达式元字符编写的过滤条件)对目标文本逐行进行匹配检查并打印出符合条件的行.

      grep有三个版本:grep,egrep和fgrep. egrep是扩展的grep,等同于grep -E,fgrep是快速grep,不支持正则表达式.

    之前觉得glob跟grep正则很相似,其实他们的区别还挺大:

      glob匹配文件名,grep匹配文件内容

      glob是全部匹配,grep是部分匹配

    正则表达式(Regular Expression,在代码中常简写为regex、regexp或RE):

      正则表达式是对字符串(包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”))操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式是一种文本模式,模式描述在搜索文本时要匹配的一个或多个字符串。

    不同版本的grep对正则表达式的支持有所不同:

      grep:默认是使用基本正则表达式(BRE)

      egrep:支持扩展的正则表达式(ERE)

      fgrep:不支持正则表达式(但搜索速度快)

    grep命令:

      命令格式:

        grep [OPTIONS] PATTERN [FILE...]

        grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]

      常用选项:

        --color=auto:对匹配到的文本着色高亮显示

        -i:忽略字符大小写

        -o:仅显示匹配到的文本自身(默认显示匹配到的文本整行)

        -v,--invert-match:显示不能被pattern匹配到的行

        -E,--extened-regexp:支持扩展的正则表达式(ERE).相当于egrep命令

        -F,--fixed-strings:相当于fgrep命令

        -q,--quiet,--silent:静默模式,不输出任何信息,取命令退出状态码时常用

        -G,--basic-regexp:支持使用基本正则表达式

        -P,--perl-regexp:支持使用pcre正则表达式(支持元字符很多)

        -e PATTERN,--regexp=PATTERN:使用多模式

        -f FILE,--file=:FILE为每行包含了一个pattern的文本文件,即grep script,把模式写在一个文件里,通过读取文件(脚本文件),来匹配

        -c:显示统计匹配到的行数

        -r,--recursive:对目录下所有文件里的内容根据模式匹配

        -A #,--after-context=#:表示显示匹配到行的后面#行

        -B #,--before-context=#:表示显示匹配到行的前面#行

        -C #,-#,--context=#:表示显示匹配到行的前后#行

      示例:

        # grep 'root' /etc/passwd:如果模式里有变量要用双引号

        clip_image001

        # grep -v 'root' /etc/passwd:反向匹配,显示所有没有被匹配的行

        clip_image002

        # grep -i 'bash' bash.txt:忽略字符大小写

        clip_image003

        # grep -o 'root' /etc/passwd:仅显示匹配到的文本自身

        clip_image004

        # grep -q 'root' /etc/passwd:静默模式

        clip_image005

      示例

        # grep -e "r..t" -e "bash" /etc/passwd:使用多模式

        clip_image006

        # grep -f /root/test/mypat /etc/passwd:使用保存在文件里的匹配模式,模式无需加引号.

        clip_image007

        # grep -A 1 "^[op]" /etc/passwd:显示匹配到的行后面的一行

        clip_image008

        # grep -B 2 "^[op]" /etc/passwd:显示匹配到的行前面的两行

        clip_image009

        # grep -C 1 "^[op]" /etc/passwd:显示匹配到的行前后各一行

        clip_image010

    基本正则表达式元字符:

      1、字符匹配:

        .:匹配任意单个字符

        []:匹配范围内的任意单个字符

        [^]:匹配范围外的单个字符

        [:digit:]:任意单个数字

        [:lower:]:任意单个小写字母

        [:upper:]:任意单个大写字符

        [:alpha:]:任意单个字母

        [:alnum:]:任意单个字母和数字

        [:space:]:任意单个空白字符

        [:blank:]:任意单个空格和tab

        [:punct:]:任意单个标点符号

        [:cntrl:]:任意单个控制符

        [:graph:]:任意单个能显示的符号

        [:print:]:任意单个可打印符号

        [:xdigit:]:任意单个十六进制字符

      示例

        # ifconfig | grep "r..":r后跟两个字符的行

        clip_image011

        # ifconfig | grep -i "i[a-z][a-z]":不区分大小写,i后跟两个字母的行

        clip_image012

        # ifconfig | grep "i[[:alpha:]][[:space:]]":i后跟一个字母再跟一个空格的行

        clip_image013

      2、次数匹配:

        用在要指定其出现的次数的字符后面,用于限制其前面的字符要出现的次数,默认工作在贪婪模式

        *:匹配前面的字符出现的任意次(0,1或多次)

        grep "x*y":只要有y就匹配

        clip_image014

        .*:匹配任意长度的任意字符,相当于glob中的*

        grep "x.*y":在x和y之间可出现任意长度任意字符即匹配

        clip_image015

        +:匹配前面的字符至少1次(1次或多次);为转义符

        grep "x+y":y之前必须出现一个x

        clip_image016

        ?:匹配前面的字符0次或1次,即前面的字符可有可无

        grep "x?y":只要有y就匹配

        clip_image017

        {m}:匹配其前面的字符出现m次,m为非负整数

        grep "x{2}y":y前出现2次x就匹配

        clip_image018

        {m,n}:匹配其前面的字符出现m次,m为非负整数;闭区间[m,n]

        clip_image019

        {0,n}:至多n次

        clip_image020

        因为会匹配多次,所以全部都会匹配

        {m,}:至少m次

        clip_image021

      示例

        # ifconfig | grep "i[[:alpha:]]{3}":匹配i后跟3个字母的行

        clip_image022

        # ifconfig | grep "i[[:alpha:]]{3,}":匹配i后跟至少3个字母的行

        clip_image023

      3、位置锚定:

        限制使用模式搜索文本,限制模式所匹配到的文本只能出现于目标文本的哪个位置

        ^:行首锚定;用于模式的最左侧,^PATTERN

        $:行尾锚定;用于模式的最右侧,PATTERN$

        ^PATTERN$:要让PATTERN完全匹配一整行

        ^$:匹配空行;

        ^[[:space:]].*$:匹配空白行;

      示例

        # grep "^r..t" /etc/passwd:匹配r开头后跟两个字符再跟t的行

        clip_image024

        # grep "l.{3}n" /etc/passwd:匹配l后跟3个字符再跟n的行

        clip_image025

        # grep "l.{3}n$" /etc/passwd:匹配l后跟3个字符再跟n结尾的行

        clip_image026

        # grep "[[:space:]]+" /etc/passwd:匹配至少连续出现一个空格的行

        clip_image027

      单词:非特殊字符组成的连续字符(字符串)都称为单词

        <或:词首锚定,用于单词模式的左侧,格式为<PATTERN,/bPATTERN

        >或:词尾锚定,用于的承诺模式的右侧,格式为PATTERN>,PATTERN

      示例

        # grep "<r..t" /etc/passwd:匹配单词词首:r后跟两个字符再跟t的行

        clip_image028

        # grep "<r..t>" /etc/passwd:匹配单词:r后跟两个字符再跟t的行

        clip_image029

        # ifconfig | grep "<[0-9]{3}>":匹配单词:三个数字

        clip_image030

      更多实例:

        1、显示/etc/passwd文件中不以bash结尾的行

        # grep -v 'bash$' /etc/passwd

        clip_image031

        2、找出/etc/passwd文件中的三位或四位数

        # grep '<[0-9]{3,4}>' /etc/passwd

        clip_image032

        3、找出/etc/grub2.cfg文件中,以至少一个空白字符开头,后面又跟了一非空白字符的行

        # grep '^[[:space:]]+[^[:space:]]' /etc/grub2.cfg

        clip_image033

        4、找出"netstat -tan"命令的结果中,以‘LISTEN’后跟0或多个空白字符结尾的行

        # netstat -tan | grep 'LISTEN[[:space:]]*$'

        clip_image034

        5、找出“fdisk -l”命令结果中,以/dev/后跟sd或hd及一个小写字母的行

        # fdisk -l | grep '/dev/[sh]d[a-z]>'

        clip_image035

        6、找出“ldd /usr/bin/cat”命令的结果中的文件路径

        # ldd /usr/bin/cat | grep -o '/[^[:space:]]+'

        clip_image036

      4、分组与引用:

        (PATTERN):将此PATTERN匹配到的字符当作一个不可分割的整体进行处理

        注意:分组括号中的模式匹配到的字符会被正则表达式引擎自动记录于内部变量中,这些变量是1,2,3,...

        例如:pat1(pat2)pat3(pat4(pat5)pat6)

         :模式中的第n个左括号以及与之匹配的右括号之间的模式所匹配到的字符串(不是模式,而是模式匹配的结果)

        1:表示第一组括号总的PATTERN匹配到的的字符串;上例:pat2

        2:表示第二组括号总的PATTERN匹配到的的字符串;上例:pat4(pat5)pat6

        3:表示第三组括号总的PATTERN匹配到的的字符串;上例:pat5

        ...

        示例,文档test内容如下:

        he love his lover

        he like his lover

        he love his liker

        he like his liker

        .*l..e.*l..er

        (l..e).*1r

        # grep -o 'l..e.*l..er' test:不能完成精确匹配

        clip_image037

        # grep -o '(l..e).*1r' test:分组可完成精确匹配

        clip_image038

        后向引用:引用前面的括号中的模式所匹配到的字符串

    egrep命令:

        命令格式

          egrep [OPTIONS] PATTERN [FILE...]

        命令选项:

          egrep的选项与grep相同

        扩展正则表达式的元字符:无需转义符

        字符匹配:

          .:匹配任意单个字符

          []:匹配范围内的任意单个字符

          [^]:匹配范围外的单个字符

          [:digit:]:任意单个数字

          [:lower:]:任意单个小写字母

          [:upper:]:任意单个大写字符

          [:alpha:]:任意单个字母

          [:alnum:]:任意单个字母和数字

          [:space:]:任意单个空格

          [:blank:]:任意单个空格和tab

          [:punct:]:任意单个标点符号

        次数匹配:

          *:匹配前面的字符(可有可无)出现的任意次(0,1或多次)

          ?:匹配前面的字符0次或1次,即前面的字符可有可无

          +:匹配前面的字符至少1次(1次或多次)

          {m}:匹配其前面的字符出现m次,m为非负整数

          {m,n}:匹配其前面的字符出现m次,m为非负整数

          {0,n}:至多n次

          {m,}:至少m次

        位置锚定:

          ^:行首锚定;用于模式的最左侧,^PATTERN

          $:行尾锚定;用于模式的最右侧,PATTERN$

          ^PATTERN$:要让PATTERN完全匹配一整行

          ^$:匹配空行

          <,:词首锚定,用于单词模式的左侧,格式为<PATTERN,/bPATTERN

          >,:词尾锚定,用于的承诺模式的右侧,格式为PATTERN>,PATTERN

        分组及引用:

          (pattern):分组,括号中的模式匹配到的字符会被存储于正则表达式引擎内部的变量中

          后向引用:1,2,3,...

        或者:

          a|b:a或者b

          C|cat:表示C或cat

          (C|c)at:表示Cat或cat

      egrep实例:

          1、显示/etc/passwd文件中不以bash结尾的行

          # egrep -v 'bash$' /etc/passwd

          clip_image039

          2、找出/etc/passwd文件中的三位或四位数

          # egrep '<[0-9]{3,4}>' /etc/passwd

          clip_image040

          3、找出/etc/grub2.cfg文件中,以至少一个空白字符开头,后面又跟了一非空白字符的行

          # egrep '^[[:space:]]+[^[:space:]]' /etc/grub2.cfg

          clip_image041

          4、找出"netstat -tan"命令的结果中,以‘LISTEN’后跟0或多个空白字符结尾的行

          # netstat -tan | egrep 'LISTEN[[:space:]]*$'

          clip_image042

          5、找出“fdisk -l”命令结果中,以/dev/后跟sd或hd及一个小写字母的行

          # fdisk -l | egrep '/dev/[sh]d[a-z]>'

          # fdisk -l | egrep '/dev/(s|h)d[a-z]>'

          clip_image043

          6、找出“ldd /usr/bin/cat”命令的结果中的文件路径

          # ldd /usr/bin/cat | egrep -o '/[^[:space:]]+'

          clip_image044

          7、找出/proc/meninfo文件中,所有以大写或小写s开头的行,至少用三种方式实现

          # egrep "^(s|S)" /proc/meminfo

          # grep "^[sS]" /proc/meminfo

          # grep -i "^s" /proc/meminfo

          clip_image045

          8、显示当前系统上root,centos,或slackware用户的相关信息

          # egrep "^(root|centos|slackware)>" /etc/passwd

          # egrep "^(root|centos|slackware):" /etc/passwd

          clip_image046

          9、echo输出一个绝对路径,使用grep取出基名

          # echo /etc/passwd/ | egrep -o "[^/]+/?$"

          clip_image047

          10、找出ifconfig命令结果中的1-255之间的整数

          # ifconfig| egrep "<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])>"

          clip_image048

          11、添加用户bash、testbash、及nologin,要求前三个用户的默认shell为/bin/bash,而后找出其用户名与shell相同的用户

          # egrep "^([a-z0-9]+)>.*1$" /etc/passwd

          clip_image049

  • 相关阅读:
    How does “void *” differ in C and C++?
    Can we use function on left side of an expression in C and C++?
    apache配置局域网访问
    apache以天为单位生成日志
    尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
    IIS 处理程序“PageHandlerFactory-Integrated”
    IIS无法识别的属性targetFramework
    php开启短标签支持
    Notepad++配色方案
    vim常用操作整理
  • 原文地址:https://www.cnblogs.com/Q--T/p/7901409.html
Copyright © 2011-2022 走看看