09-grep/egrep/fgrep命令与基本正则表达式
09-grep/egrep/fgrep命令与基本正则表达式

09-grep/egrep/fgrep命令与基本正则表达式

回顾:

bash的特性:hash,变量

  • 命令hash: hash命令

  • 变量:

    • 本地变量(作用域为当前shell进程)
    • 环境变量(当前shell进程及其子进程)
    • 局部变量
    • 位置参数变量
    • 特殊变量
  • 变量赋值: name=value, export name=value, delcare -x name=value

  • 变量引用:$name, ${name}

    有时候,变量引用的花括号{}不可以省略:

    [lemon@VM-4-10-centos ~]$ animal=sheep
    [lemon@VM-4-10-centos ~]$ echo ${animal}
    sheep
    [lemon@VM-4-10-centos ~]$ echo $animal
    sheep
    [lemon@VM-4-10-centos ~]$ echo "There are some $animal"
    There are some sheep
    [lemon@VM-4-10-centos ~]$ echo "There are some $animals"
    There are some
    [lemon@VM-4-10-centos ~]$ echo "There are some $animal s"
    There are some sheep s
    [lemon@VM-4-10-centos ~]$ echo "There are some ${animal}s"
    There are some sheeps
  • 撤销变量:unset name

    image-20230609143828295

  • bash脚本编程,运行脚本

    #!/bin/bash
    #
  • bash的配置文件:

    • profile类:登录式shell (su -l)
    • 登录式shell: /etc/profile --> /etc/profiled.d/* --> ~/.bashrc --> /etc/bashrc
    • bashrc类:非登录式shell (su,图像页面打开的命令行窗口,shell脚本运行时的shell)
    • 非登录式shell: ~/.bashrc -->/etc/bashrc --> /etc/profile.d/*.sh

文本处理工具

Linux上文本处理三剑客:

  • grep,egrep,fgrep:文本过滤工具;(模式:pattern)
    • grep: 基本正则表达式,-E, -F
    • egrep:扩展正则表达式, -G, -F
    • fgrep: 不支持正则表达式, -F
  • sed:文本编辑工具;strem editor,流编辑器;
  • awk:文本报告生成器;(格式化文本);Linux上的实现为gawk;

都会用到正则表达式(Regual Expression,简写REGEXP):

正则表达式:由一类特殊字符及文本字符所编写的模式,其中有些字符不表示其字面意义,而是用于表示控制或通配的功能

分两类:

  • 基本正则表达式:BRE
  • 扩展正则表达式:ERE

grep

grep:Global search REgual expression and Print out the line

作用:文本搜索工具,根据用户指定的“模式(过滤条件)”对目标文本逐行进行匹配检查;打印匹配到的行;

模式:由正则表达式的元字符及文本字符所编写出的过滤条件;

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

image-20230609150149949

选项操作

OPTΠONS:

  • --color=auto: 对匹配到的文本着色后高亮显示;当然,这个是默认的,因为超链接别名alias

    image-20230609162222801

  • -i: ignorecase,忽略字符的大小写;

    image-20230609162339834

  • -o: 仅显示匹配到的字符串本身;

    image-20230609162422968

  • -v: --Invert-match:显示不能被模式匹配到的行,就是命中字符以外的,反着来的;

  • image-20230609162619834

  • -E:支持使用扩展的正则表达式元字符;

  • -q,-quiet,-silent: 静默模式,即不输出任何信息;

    image-20230609163954782

  • -A #:after 显示后#行

  • -B # :before, 显示前#行

    image-20230609161801591

  • -C #:context, 前后各#行

    image-20230609162032911

基本正则表达式元字符

字符匹配

  • .:匹配任意单个字符;

  • []:匹配指定范围内的任意单个字符;

  • [^]:匹配指定范围外的任意单个字符:[:digit:][:lower:][:upper:].[:alpha:][:alnum:][:punct:][:space:]

    # 匹配包含:r和t之间任意两个字符
    [root@rhino010 ~]# grep "r..t" /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    operator:x:11:0:operator:/root:/sbin/nologin
    ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
    ftpuser:x:1002:50::/var/ftp/public_root:/bin/bash
    dockerroot:x:994:990:Docker User:/var/lib/docker:/sbin/nologin
    # 匹配包含:r和t之间两个字母
    [root@rhino010 ~]# grep "r[[:alpha:]][[:alpha:]]t" /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    operator:x:11:0:operator:/root:/sbin/nologin
    ftpuser:x:1002:50::/var/ftp/public_root:/bin/bash
    dockerroot:x:994:990:Docker User:/var/lib/docker:/sbin/nologin
    # 匹配包含:r和t之间,第一个非字母,第二个为字母(主要把^符号放在前面,表示非,取反)
    [root@rhino010 ~]# grep "r[^[:alpha:]][[:alpha:]]t" /etc/passwd
    ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
    ftpuser:x:1002:50::/var/ftp/public_root:/bin/bash

匹配次数

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

  • *:匹配其前面的字符任意次;0,1,多次;
  • .*:匹配任意长度的任意字符;
  • \?:匹配其前面的字符0次或1次:即其前面的字符是可有可无的;
  • \+:匹配其前面的字符1次或多次;即其面的字符要出现至少1次;
  • \{m\}:匹配其前面的字符m次;
  • \{m, n\}:匹配其前面的字符 至少m次,至多n次
  • \{0, n\}:匹配其前面的字符 至多n次
  • \{m, \}:匹配其前面的字符 至多n次

image-20230609170749111

image-20230609171416136

位置锚定

  • ^行首锚定;用于模式的最左侧;

    grep '^root' /etc/passwd

  • $行尾锚定;用于模式的最右侧;

    grep '^root' /etc/passwd

  • ^PATTERN$:用于PATTERN来匹配整行;

    • ^$: 空白行;
    • ^[[:SPACE:]]*$: 空行或包含空白字符的行;
  • 单词:连续的非特殊字符组成的字符(字符串)都称为单词

  • \<\b:词首锚定, 用于单词模式的左侧;

  • \>\b: 词尾锚定,用于单词模式的右侧;

  • \<PATTERN\>:匹配完整单词

练习:

  • 显示/etc/passwd文件中不以/bin/bash结尾的行;

    grep  -v '/bin/bash$'  /etc/passwd
  • 找出/etcpasswd文件中两位数或三位数;

    # grep '[[:digit:]]\{2,3\}'  /etc/passwd
    grep '\'  /etc/passwd
  • 找出/etc/rc.d/rc.sysinit(centos6)或/etc/grub2.cfg(centos7)文件中,以至少一个空白字符开头,且后面非空白字符的行;

    grep "^[[:space:]]\+[^[:space:]]" /etc/grub2.cfg
  • 找出"netstat -tan”命令的结果中以LISTEN后跟0、1个或多个空白字符结尾的行;

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

分组及引用

\(\):将一个或多个字符捆绑在一起,当做一个整体处理

\(xy\)*ab

Note:分组括号中的模式匹配到的内容会被正则表达式引擎自动记录于内部的变量中,这些变量为:

  • \1:模式从左侧起,第一个左括号以及与之匹配的右括号之间的模式所匹配到的字符:
  • \2:模式从左侧起,第二个左括号以及与之匹配的右括号之间的模式所匹配到的字符:
  • \3: ...
[root@VM-4-10-centos ~]# cat lovers.txt
He likes his lover.
He loves his lover.
She likes her liker.
She loves her liker.
[root@VM-4-10-centos ~]# grep "\(l..e\).*\1" lovers.txt
He loves his lover.
She likes her liker.
[root@VM-4-10-centos ~]# grep "\(l..e\).*\2" lovers.txt
grep: 无效的向后引用
[root@VM-4-10-centos ~]# grep "^\(r..t\).*\1" /etc/passwd
root:x:0:0:root:/root:/bin/bash

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

egrep

概述

extend,支持扩展的正则表达式,实现类似于grep文本过滤功能: grep -E

egrep [OPTIONS] PATTERN [FILE...]

选项:

  • -i, -o, -v, -q, -A, -B, -C

  • -G:支持基本正则表达式

扩展正则表达式的元字符:

  • 字符匹配:
    • .:任意单个字符
    • []:指定范围内的任意单个字符
    • [^]:指定范围外的任意单个字符
  • 次数匹配:
    • *:任意次,0,1或多次:
    • ?:0次或1次,其前的字符是可有可无的:
    • +:其前字符至少1次;
    • {m}:其前的字符m次;
    • {m,n}:至少m次,至多n次;
      {0,n}
      {m,}
  • 位置锚定
    • ^:行首锚定;
    • $:行尾锚定;
    • \<,\b:词首锚定;
    • \>,\b:词尾锚定;
  • 分组及引用
    • ():分组:括号内的模式匹配到的字符会被记录于正则表达式引擎的内部变量中;
    • 后向引用:\1,\2,…
      或:
    • a|b:a或者b
    • C | cat:C或cat
    • (clC)at: Cat或cat

练习:

  • 显示/etc/passwd文件中不以/bin/bash结尾的行;

    egrep  -v '/bin/bash$'  /etc/passwd
    # grep -E
  • 找出/etcpasswd文件中两位数或三位数;

    egrep '\'  /etc/passwd
    # grep -E
  • 找出/etc/rc.d/rc.sysinit(centos6)或/etc/grub2.cfg(centos7)文件中,以至少一个空白字符开头,且后面非空白字符的行;

    egrep "^[[:space:]]+[^[:space:]]" /etc/grub2.cfg
    # grep -E
  • 找出"netstat -tan”命令的结果中以LISTEN后跟0、1个或多个空白字符结尾的行;

    netstat -tan | egrep "LISTEN[[:space:]]*$"
    # grep -E
  • 找出/proc/meminfo文件中,所有在大写或小写S开头的行:至少有三种实现方式;

    grep  -i '^S' /proc/meminfo
    egrep  '^(s|S)' /proc/meminfo
    grep  '^[Ss]' /proc/meminfo
  • 显示当前系统上root、centos或user1用户的相关信息

    grep -E "^(root|vents|user1)\>"
  • 找出/etc/rc.d/Init.d/functions文件中某单词后面跟一个小括号的行

    egrep '[_[:alnum:]]+\(\)' /etc/rc.d/init.d/functions
    egrep '\<.>+\(\)' /etc/rc.d/init.d/functions
  • 使用echo命令输出一绝对路径,使用egrep取出基名;

    # 找词尾的非斜线字符
    echo /home/user/documents/file.txt | egrep -o '[^/]+/?$'
    echo /home/user/documents/file.txt | egrep -o '[^/]+$'
    
    # 取路径名,类似于对其执行dirname命令的结果
    
  • 找出ifconfig命令结果中的1-255之间的数值

    ifconfig | grep -E -o "\"
  • 课外作业:找出ifconfig命令结果中的IP地址

    ifconfig | grep -E -o '[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]'
  • 添加用户bash,testbash,basher以及nologin(其shel为/sbln/nologin):而后找出/etc/passwd文件中用户名同shell名的行;

    [root@VM-4-10-centos data]# useradd bash
    [root@VM-4-10-centos data]# useradd basher
    [root@VM-4-10-centos data]# useradd -s /sbin/nologin nologin
    [root@VM-4-10-centos data]# useradd testbash
    [root@VM-4-10-centos data]# tail /etc/passwd
    lighthouse:x:1002:1002::/home/lighthouse:/bin/bash
    lemon:x:1003:1003::/home/lemon:/bin/bash
    tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
    redis:x:995:990:Redis Database Server:/var/lib/redis:/sbin/nologin
    x:x:1004:1004::/home/x:/bin/bash
    user3:x:1005:1005::/home/user3:/bin/bash
    bash:x:1006:1006::/home/bash:/bin/bash
    basher:x:1007:1007::/home/basher:/bin/bash
    nologin:x:1008:1008::/home/nologin:/sbin/nologin
    testbash:x:1009:1009::/home/testbash:/bin/bash
    
    [root@VM-4-10-centos data]# grep -E "^([^:]+\>).*\1$" /etc/passwd
    sync:x:5:0:sync:/sbin:/bin/sync
    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
    halt:x:7:0:halt:/sbin:/sbin/halt
    bash:x:1006:1006::/home/bash:/bin/bash
    nologin:x:1008:1008::/home/nologin:/sbin/nologin

    fgrep

    不支持正则表达式元字符,当无需要用到元字符去编写模式时,使用fgrep性能更好

发表回复

您的电子邮箱地址不会被公开。