grep

  1. Linux文本处理工具:
    • 文本搜索
      • 文本搜索工具,根据用户指定的文本模式(搜索条件)对目标文件进行逐行搜索,显示能匹配到的行。
      • 语法格式:
        grep [option]... 'PATTERN' FILE... --color=auto
  • 正则表达式:

    • 一类字符所书写的模式,其中许多字符不表示其字面意义,而是表达控制或通配等功能;
    • 元字符:不表示其字面意义,而用于额外功能性描述
      正则表达式:正则表达式引擎
  • 基本正则表达式:grep

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

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

  • 基本正则表达式的元字符:

    • 字符匹配:
      • .: 匹配任意单个字符
      • [0-9], [[:digit:]]
      • [a-z], [[:lower:]]
      • [A-Z], [[:upper:]]
      • [[:space:]]
      • [[:punct:]]
      • [[:alpha:]]
      • [[:alnum:]]
      • [ ] 匹配指定范围内的任意单个字符
      • : 任意长度,它前面的字符可以出现任意次
        例如:x
        y
        xxy, xyy, y,
        • ?: 0次或1次,它前面的字符是可有可无的
          例如:x?y
          xy, y, ay
        • {m}: m次,它前的字符要出现m次
          例如:x{2}y
          xy, xxy, y, xxxxy, xyy
        • {m,n}: 至少m次,至多n次
          例如:x{2,5}y
          xy, y, xxy
        • {m,}:至少m次
          {0,n}: 至多n次
      • .*:任意长度的任意字符 工作于贪婪模式:尽可能多的去匹配
        • 位置锚定:
          • ^: 行首锚定;
            写在模式最左侧
          • $: 行尾锚定:
            写在模式最右侧
          • ^$: 空白行
    • 不包含特殊字符的连续字符组成的串叫单词:
      • <: 词首,出现于单词左侧,\b
      • >: 词尾,出现于单词右侧, \b
        char>
      • 分组:
        ()
        例如:(ab)*
        分组中的模式匹配到的内容,可由正则表达式引擎记忆在内存中,之后可被引用
        引用:
        例如(ab(x)y).(mn)
        有编号:自左而后的左括号,以及与其匹配右括号
        (a(b(c))mn(x)).
        \1
        #: 引用第n个括号所匹配到的内容,而非模式本身
        例如:
        (ab?c).*\1
        abcmnaaa
        abcmnabc
        abcmnac
        acxyac
        命令选项:
        -v: 反向选取
        -o: 仅显示匹配的字串,而非字串所在的行
        -i: ignore-case,忽略字符大小写
        -E: 支持使用扩展正则表达式
        -A #
        -B #
        -C #
  • 练习:

    • 显示/proc/meminfo文件中以大写或小写S开头的行;
      grep -i '^s' /proc/meminfo
      grep '^[Ss]' /proc/meminfo
      grep -E '^(S|s)' /proc/meminfo
    • 显示/etc/passwd文件中其默认shell为非/sbin/nologin的用户;
      grep -v "/sbin/nologin$" /etc/passwd | cut -d: -f1
    • 显示/etc/passwd文件中其默认shell为/bin/bash的用户;
      进一步:仅显示上述结果中其ID号最大的用户;
      grep "/bin/bash$" /etc/passwd | sort -t: -k3 -n | tail -1 | cut -d: -f1
    • 找出/etc/passwd文件中的一位数或两位数;
      # grep "<[0-9][0-9]?>" /etc/passwd
      # grep "<[0-9]{1,2}>" /etc/passwd
    • 显示/boot/grub/grub.conf中以至少一个空白字符开头的行;
      # grep "^[[:space:]]{1,}" /boot/grub/grub.conf
    • 显示/etc/rc.d/rc.sysinit文件中,以#开头,后面跟至少一个空白字符,而后又有至少一个非空白字符的行;
      # grep "#[[:space:]]{1,}[[:space:]]{1,}" /etc/rc.d/rc.sysinit
    • 找出netstat -tan命令执行结果中以'LISTEN'结尾的行;
      # netstat -tan | grep "LISTEN[[:space:]]*$"
  • 添加用户bash, testbash, basher, nologin(SHELL为/sbin/nologin),而找出当前系统上其用户名和默认shell相同的用户;
    # grep "^([[:alnum:]]{1,}):.*\1$" /etc/passwd

  • 扩展题:新建一个文本文件,假设有如下内容:
    He like his lover.
    He love his lover.
    He like his liker.
    He love his liker.
    找出其中最后一个单词是由此前某单词加r构成的行。
    (l..e).*\1r
    扩展正则表达式:
    字符匹配:
    .

    次数匹配:
    :任意次
    ?: 0次或1次
    +: 至少1次;
    {m}: 精确匹配m次
    {m,n}: 至少m次,至多n次
    {m,}
    {0,n}
    锚定:
    ^
    $
    <, \b
    >, \b
    ^$, ^[[:space:]]
    $
    分组:
    ()
    引用:\1, \2, \3
    或者:
    a|b: a或者b
    con(C|c)at
    concat或conCat?
    conC或cat
    grep -E 'PATTERN' FILE...
    egrep 'PATTERN' FILE...
    练习:使用扩展的正则表达式

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

  • 找出/etc/rc.d/init.d/functions文件中某单词后跟一组小括号“()”行;
    # grep -o -E "<[[:alnum:]]+>()" /etc/rc.d/init.d/functions

  • 使用echo命令输出一个路径,而后使用grep取出其基名;
    echo "/etc/sysconfig/" | grep -o -E "[[:alnum:]]+/?"
    echo "/etc/sysconfig/" | grep -o -E "[^/]+/?$" | cut -d/ -f1

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

  • 挑战题:写一个模式,能匹配合理的ipv4地址;
    1.0.0.1-239.255.255.255
    fgrep 'PATTERN' FILE...
    不支持正则表达式

  • 回顾:
    基本正则表达式元字符:
    字符匹配:., ., [], ^
    次数匹配:(通过分组的方式对不止一个字符做次数匹配) , ?, +, {m,n}
    位置锚定:^, $, < (\b), > (\b)
    分组及引用:(), \n
    扩展的正则表达式:
    次数匹配:
    , ?, +, {m,n}
    分组引用:(), \n
    或者:a|b
    grep, egrep, fgrep
    --color=auto
    -v
    -o
    -i
    -A, -B, -C
    -E
    grep [option] 'PATTERN'
    明确要求搜索子目录:grep -r
    或忽略子目录:grep -d skip
    grep "0{1,2}" /tmp/passwd --color 筛选有一个和两个0的行
    grep "(root)(:).
    \2\1" /tmp/passwd 匹配root: .* :root /2/1 引用前面匹配内容
    grep -c bash$ /etc/passwd -c 统计个数 -r 查询目录及子目录
    -r -l 查询递归,不显示行,只显示匹配的文件 ‘.$’以.结尾 ‘0{2}’两个0
    egrep -v "#.*$|^$" /etc/ipsec.conf //过滤#号开头与空白行
    grep -E '123|abc' filename // 找出文件(filename)中包含123或者包含abc的行
    egrep '123|abc' filename // 用egrep同样可以实现
    awk '/123|abc/' filename // awk 的实现方式
    grep pattern1 files | grep pattern2 :显示既匹配 pattern1 又匹配 pattern2 的行。

你可能感兴趣的:(grep)