grep egrep 用法以及其相应的正则表达式


一、grep、egrep命令

  本文中主要介绍了linux系统下grep egrep fgrep命令和正则表达式的基本参数和使用格式、方法。

 

 1.grep的定义:   

  grep(global search regular RE ) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它只能使用基本的正则表达式来搜索文本,并把匹配的行打印出来。

  grep是很常见也很常用的命令,它的主要功能是进行字符串数据的比较,然后符合用户需求的字符串打印出来,但是主意,grep在数据中查找一个字符串时,是以“整行”为单位进行数据筛选的。

 

 2.grep命令的作用:

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

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

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

    

 3.grep命令基本用法

   格式:grep [OPTIONS] PATTERN [FILE...]

 

  grep常用选项一:

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

       -i:忽略字符大小写;    grep -i  /etc/passwd

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

       -v,--invert-match:反向匹配,即显示没有'搜索字符串'内容的那行; 

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

             ~]# grep -v "bash$" /etc/passwd

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

      -a:在二进制文件中,以文本文件的方式搜索数据

        -c:计算找到'搜索字符串'的次数;

      -n:输出行号;

           

       -A #:after ,显示匹配到字符那行的后面#行;

       -B #:before,显示匹配到字符那行的前面#行;

       -C #:context,显示匹配到字符那行的前后#行;

 

   grep 常用选项之二:

       -E,--extended-regexp:支持使用扩展正则表达式,相当于egrep.

       -F,--fixed-strings:支持使用固定字符串,不支持正则表达式,相当于fgrep;

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

       -P,--perl-regexp:支持使用pcre正则表达式;

       -e PATTERN,--regexp=PATTERN:多模式机制;     

      -f FILE, --file=FILE:FILE为每行包含了一个pattern的文本文件,即grep script;

 

      -A NUM, --after-context=NUM 显示匹配到字符那行的后面#行;

      -B NUM, --before-context=NUM 显示匹配到字符那行的前面#行;

      -C NUM, -NUM, --context=NUM 显示匹配到字符那行的前后#行;

 

 4.egrep的定义: 

   egrep命令是一个搜索文件获得模式,使用该命令可以任意搜索文件中的字符串和符号,也可以为你搜索一个多个文件的字符串,一个提示符可以是单个字符、一个字符串、一个字、一个句子。egrep支持使用扩展正则表达式的grep命令,相当于grep -E。

 5.egrep命令的作用:

   Linux egrep命令用于在文件内查找指定的字符串。

   egrep执行效果与"grep-E"相似,使用的语法及参数可参照grep指令,与grep的不同点在于解读字符串的方法。

   egrep是用extended regular expression语法来解读的,而grep则用basic regular expression 语法解读,extended regular expression比basic regular expression的表达更规范。

 

 6.egrep命令基本用法

    格式:egrep [OPTIONS] PATTERN [FILE...]

     

    常用选项:

      -c :仅显示匹配行的计数。

      -e :模式 指定一个模式。这象一个简单的模式但是它在模式以一个-(负号)开始时很有用。

      -f :StringFile 指定包含字符串的文件。

      -h :当处理多个文件时排除文件名。

      -i :当进行比较时忽略字符的大小写。

      -n :在每行之前加上该行在文件中的相对行号。

      -q :禁止所有的输出到标准输出,不管匹配行。如果选中输入行,以 0 状态退出。

      -s :仅显示出错消息。这点对检查状态有用。

      -v :显示除了与指定的模式匹配的行之外的所有行。

      -w :执行单词搜索。

      -x :显示与指定模式精确匹配而不含其它字符的行。

      -y :当进行比较时忽略字符的大小写

 

二、正则表达式

1.基本定义:

  正则表达使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。简而言之,正则表达式就是处理字符串的方法,以行为单位进行字符串的处理,通过一些特殊符号的辅助,可以让用户轻松搜索/替换某特定的字符串。

  正则表达式分为两类:基本的正则表达式和扩展的正则表达式。

2.grep 相应的正则表达式详细介绍

  2.1、基本的正则表达式:

   (1)元字符:

       .:匹配任意单个字符

        例:查找包含student且student后面带一个字符的行

        grep ‘student.’ /etc/passwd 

     (模式可以用单引号和双引号,如果模式中要做变量替换时则必须用双引)     

      [] :匹配指定范围内的任意单个字符,[abc],[a-z],[0-9],[a-zA-Z]

        例:查找带有数字的行

          grep ‘[0-9]’ /etc/passwd

      [^] :匹配指定范围外的任意单个字符

        例:查找没有小写字母的行。

          grep ‘[^a-z]’ /etc/inittab

     [:space:]:表示空白字符;

     [:punct:]:表示所有标点符号的集合;

     [:lower:]:表示所有的小写字母;

     [:upper:]:表示所有的大写字母;

     [:alpha:]:表示大小写字母;

     [:digit:]:表示数字;

     [:alnum:]:表示数字和大小写字母-----使用格式[[:alnum:]]等

 

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

     * :匹配其前面的字符任意次,0,1,多次;

       例如:grep "x\+y"    abxy

     .*:匹配任意长度的任意字符 

         例如:查找包含student的行

           grep 'student.*' /etc/passwd

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

    \+:匹配其前面的字符1次或多次;即其面的字符要出现至少1次;

    \{m\}:匹配其前面的字符m次;

     \{m,n\}:匹配其前面的字符至少m次,至多n次;

     \{0,n\}:至多n次;

     \{m,\}:至少m次;

 

  (3)位置锚定:

     ^:锚定行首,用于模式的最左侧;即此字符后面的任意内容必须出现在行首。 

     $:行尾锚定,用于模式的最右侧即此字符前面的任意内容必须出现在行尾。                 ^PATTERN$:用于PATTERN来匹配整行;

       ^$:空白行;

       ^[[:space:]]*$:空行或包含空白字符的行;

 

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

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

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

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

 

 (5)分组及引用

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

        例:\(xy\)*ab

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

      \1:模式从左侧起,第一个左括号以及与之匹配的右括号之间的模式所匹配到的字符;

      \2:模式从左侧起,第二个左括号以及与之匹配的右括号之间的模式所匹配到的字符;

           ... 

       ~]# nano lovers.txt


           He loves his lover.

           He likes his lover.

           She likes her liker.

           She loves her liker.

 

       ~]# grep "\(l..e\).*\1" lovers.txt

              (1表示引用前面括号中的匹配结果)

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

  

小试牛刀:

 1、找出/etc/passwd文件中的两位数或三位数;

     ~]# grep "\<[0-9]\{2,3\}\>" /etc/passwd 


 2、找出/etc/rc.d/rc.sysinit或/etc/grub2.cfg文件中,以至少一个空白字符开头,且后面非空白字符的行;

     ~]# grep  "^[[:space:]]\+[^[:space:]]" /etc/grub2.cfg 


 3、找出"netstat -tan"命令的结果中以'LISTEN'后跟0、1或多个空白字符结尾的行;

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

    

2.2、扩展的正则表达式:

  扩展的正则表达只是在基本的正则表达上作出了一点修改,如下:

   在扩展的正则表达中\( \)==();\{ \}=={ };

   +:次数匹配,匹配其前面的字符至少出现一次,无上限;

   a|b:a或者b(二取一),其余的都一样。

   基本正则表达式,使用(){} . ? |都需要转义,在扩展正则表达中不需要加\,详细信息如下:

    (1)字符匹配的命令和用法与基本正则表达式的用法相同。

    (2)次数匹配:

      *:匹配其前面字符的任意次

     ?:匹配其前面字符的0此或着1此

     +:匹配其前面字符至少1此

    {m,n}:匹配其前面字符m到n次

    (3)字符锚定的用法和基本正则表达式的用法相同。

    (4)特殊字符:

      | : 或者的意思。

      例:grep -E 'c|cat' file  表示在文件file内查找包含c或者cat;

  

3.egrep 相应的正则表达式详细介绍:

  egrep:支持使用扩展正则表达式的grep命令,相当于grep -E;

 扩展正则表达式的元字符egrep [OPTIONS] PATTERN [FILE...]:


 3.1、基本的正则表达式:

 (1)字符匹配:

    .:任意单个字符

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

   [^ ]:范围外的任意单个字符

 

 (2)匹配次数:

     *:任意次;

     ?:0次或1次;

     +:1次或多次;

     {m}:匹配m次;

    {m,n}:至少m次,至多n次;

    {0,n}:至多n次;

    {m,}:至少m次;

 

 (3)位置锚定:

    ^:行首锚定

    $:行尾锚定

    \<, \b:词首锚定

    \>, \b:词尾锚定

 

 (4)分组及引用:

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

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

        或者:

         a|b:a或者b

         C|cat:表示C或cat

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

小试牛刀:

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

    ~]# egrep -v "bash$" /etc/passwd


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

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

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

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


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

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


 4、echo输出一个绝对路径,使用egrep取出其基名;

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


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

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


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

   ~]#useradd -s /bin/bash bash

   ~]#useradd -s /bin/bash testbash

   ~]#useradd -s /bin/bash basher

   ~]#useradd -s /sbin/nologin nologin

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