美文网首页
正则表达式和grep用法,及文本查看、处理工具

正则表达式和grep用法,及文本查看、处理工具

作者: dxldeng | 来源:发表于2017-10-21 18:46 被阅读249次

    概念

    正则表达式,又称正规表示式正规表示法、正规表达式、规则表达式、常规表示法(英语:Regular Expression,在代码中常简写为regex、regexp或RE),是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些匹配某个模式的文本。(维基百科)

    通俗地说:正则表达式就是处理字符串的方法。透过一些特殊符号的辅助,达到对文本文件内字符串的搜索,替代,删除功能。通常配合grep,sed,awk,vi等支持正则表达式的工具程序使用。例如:现在有三个行文本:hello lucy. hello world. hi,hello linux.要是我们在windows记事本里面查找hello这个单词,三个都可以查到。要是我要查询以hello开头的行就不行,就要用到正则表达式"^hello"就可以查找到了。

    分类:

    1.基本正则表达式,BRE

    2.扩展正则表达式,ERE

    正则表达式用途:

    1.从庞大的文本信息过滤出我们需要的关键信息。

    2.字符串的快速查找,定位,替换,删除等

    文本过滤工具grep详解

    grep:( Global search REgular expression and Print out the line.)它和sed(流编辑器),awk(文本报告生成器),被称为linux文本处理三剑客。

    grep用法:

    grep [OPTIONS] PATTERN [FILE...]

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

    常用选项:

    --color=auto 对匹配到的字符串高亮着色显示,centos7默认,centos6要手动设定

    -i ignorecase,忽略字母大小写。

    -o 仅显示匹配到的字符。

    -v --invert-math, 反向选择显示不能被模式匹配到的行。

    -q -quiet, --silent,静默模式,不输出任何信息。

    -A n after ,后面可加数字,除了显示该行外,后面的n行也显示出来

    -B n before,面可加数字,除了显示该行外,前面的n行也显示出来

    -C n context,显示前后各n行。

    -w  只显示符合全字符的行

    -n  显示行号,

    基本正则表达式元字符:

    字符匹配:

    1  . :匹配任意单个字符;例如,匹配/tmp/greptest文件里面字母b开头,中间包含两个任意字符,结尾字母是t的字符串:

    2.[]:匹配指定范围内的任意单个字符,中括号内可以指定多个字符;例如:匹配/tmp/greptest文件里面字母t开头,中间包含1个任意字符,结尾字母是st的字符串:

    3. [^]:匹配指定范围外的任意单个字符;例如:匹配/tmp/greptest文件里面字母oo前面不是小写字母的字符串:

    [root@dxlcentOS ~]# grep -n '[^[:lower:]]oo' /tmp/greptest    方法一

    [:digit:]所有数字,等于[0-9]

    [:lower:]小写字母,等于[a-z]

    [:upper:]大写字母,等于[A-Z]

    [:alpha:]所有字母,等于[a-z][A-Z]

    [:alnum:]所有数字和字母,等于[a-z][A-Z][0-9]

    [:punct:]特殊符号字符,例如!,@,#,$等

    [:space:]空白字符,包括空格、tab、换行、分页符

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

    1.  *:匹配其前面的字符任意次;0,1,多次;例如:匹配/tmp/greptest文件里面字母g前面跟o和g任意次

    2    .*:匹配任意长度的任意字符。例如:匹配/tmp/greptest文件里面字母g和g之间出现的任意字符

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


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

    5.  \{m\}:匹配其前面的单个连续出现字符m次;例如:匹配/tmp/greptest文件里面重复出现3次的字母o

    6.  \{m,n\}:匹配其前面的单个字符连续出现至少m次,至多n次;例如:匹配/tmp/greptest文件里面重复出现最少3次,最多4次的字母o

    7.  \{0,n\}:匹配单个字符连续出现至多n次。得出的匹配结果是有一个字母o都匹配,比较乱。

    8.  \{m,\}:匹配前面单个字符至少m次,例如匹配字符o连续出现最少5次

    字符位置锚定:

    1.^:行首锚定;用于模式的最左侧的单词或字符;例如:匹配/tmp/greptest文件里面行首是the开头的行。

    [root@dxlcentOS ~]# grep -n '^the' /tmp/greptest

    12:the symbol '*' is represented as start.

    24:the kiio pooo

    匹配/tmp/greptest文件里面行首是小写字母开头的行

    [root@dxlcentOS ~]# grep -n '^[a-z]' /tmp/greptest

    2:apple is my favorite food.

    4:this dress doesn't fit me.

    10:motorcycle is cheap than car.

    2.$:行尾锚定;用于模式的最右侧;例如:匹配/tmp/greptest文件里面ww字符结尾的行

    [root@dxlcentOS ~]# grep -n "ww$" /tmp/greptest

    26:these iisufu www

    3.  ^PATTERN$:用于指定的PATTERN来匹配整行;例如:匹配/tmp/greptest文件里面以TH开头的行

    4.^$:空白行;

    [root@dxlcentOS ~]# grep -n '^   /tmp/functions | wc -l

    87

    [root@dxlcentOS ~]# grep -n '^$' /tmp/functions

    6:

    8:

    .......

    5.  ^[[:space:]]*$:匹配空行或包含空白字符的行;例如:匹配/tmp/greptest文件里面的空行

    单词匹配:不包含特殊字符,由字母组成的连续字符(字符串)都称为单词;

    1.  \< 或 \b:词首锚定,用于单词模式的左侧;例如匹配字母kii开头的单词

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

    3.  \<模式\>:匹配完整单词;例如,匹配good这个单词

    练习:

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

    [root@dxlcentOS ~]# grep -v  "/bin/bash$" /etc/passwd

    bin:x:1:1:bin:/bin:/sbin/nologin

    daemon:x:2:2:daemon:/sbin:/sbin/nologin

    ...

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

    [root@dxlcentOS ~]# grep  "\b[0-9]\{2,3\}\b" /etc/passwd

    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

    operator:x:11:0:operator:/root:/sbin/nologin

    games:x:12:100:games:/usr/games:/sbin/nologin

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

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

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

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

    分组及引用

    \(\):分组。

    这个概念思考了很久,比较难描述,用实例说明:

    在/tmp/fenzu文件里里面,执行[root@dxlcentOS ~]# grep "dogo\{2\}" /tmp/fenzu,\{2\}是匹配前面的字符o两次,如果我要匹配连续出现的dogdog怎么做?

    这个时候,就需要用到分组了,把dog分作一组,作为一个字符串的整体进行匹配就可以了。

    上图所示:\(dog\)表示将dog作为一个字符串整体,\{2\}影响的字符就是前面的dog这个字符串整体。

    \(dog\)\{2\}  这个正则表达式表示dog字符串连续出现两次,dogdog。

    所以 \(   \)就是分组。括号内的内容看做一个整体,一个分组进行匹配。通俗地理解就是把多个字符串用括号括起来,组成一个整体进行匹配。

    后向引用:前提示前面有了分组才能进行。

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

    \1:模式从左侧起,表示引用整个正则表达式第一个分组中的正则所匹配的结果

    \2:模式从左侧起,表示引用整个正则表达式第2个分组中的正则所匹配的结果

    \3

    ...

    概念理解难懂,还是通过实例说明:在/tmp/yiny文件有如下内容,

    He loves his lover.

    He likes his lover.

    She likes her liker.

    She loves her liker.

    假如我要匹配like和love 这俩个单词:

    现在我改变需求了,我要把his和her前后的like和love都相同的行取出来,可以这样做:

    所以,后向引用通俗理解就是匹配前后一样的字符串。\(l..e\),\(like\) 表示分组 。 把前面分组后的匹配结果再引用一次。  \1  表示后向引用。    .* 表示love和like中间的任意字符。\(l..e\)匹配到love后,\1就引用了love;\(like\)匹配到like后,\1就引用了llike。这就是后向引用。

    扩展正则表达式egrep:

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

    egrep [OPTIONS] PATTERN [FILE...]

    选项:

    -i, -o, -v, -q, -A, -B, -C ,和基本grep没什么区别。

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

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

    字符匹配:

    .:任意单个字符

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

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

    次数匹配:

    *:任意次,0,1或多次;

    ?:0次或1次,其前的字符是可有可无的;

    +:其前字符至少1次;

    {m}:其前的字符m次;

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

    {0,n}  表示之前出现的字符至少连续出现0次,最多n次才会被匹配到。

    {m,}  表示之前出现的字符至少连续出现m次才会被匹配到。

    位置锚定

    ^:行首锚定;

    $:行尾锚定;

    \<, \b:词首锚定;

    \>, \b:词尾锚定;

    分组及引用:

    ():分组和基本正则表达式用法相同

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

    | 或:“|” 在扩展表达式中表示或

    a|b:a或者b;

    C|cat:C或cat

    (c|C)at:cat或Cat

    (com|net)表示com或net

    例如:

    总结:扩张正则和基本正则的元字符用法差不多,区别就是扩张正则对于小括号和花括号不用逃脱符\,阅读和使用起来简明一些。

    综合练习:

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

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

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

    ~]# grep -E "^(s|S)" /proc/meminfo

    [root@dxlcentOS ~]# egrep  "^(s|S)" /proc/meminfo

    SwapCached:            0 kB

    SwapTotal:      2097148 kB

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

    ~]# grep -E "^(root|centos|user1)\>" /etc/passwd

    [root@dxlcentOS ~]# grep -E "^(root|centos|user1)" /etc/passwd

    3、找出/etc/rc.d/init.d/functions文件中某单词后面跟一个小括号的行;

    ~]# grep  -E  -o  "[_[:alnum:]]+\(\)"  /etc/rc.d/init.d/functions

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

    ~]# echo /etc/sysconfig/ | grep  -E  -o  "[^/]+/?$"

    进一步:取出其路径名;类似于对其执行dirname命令的结果;

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

    ~]# ifconfig | grep  -E  -o  "\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>"

    6、取出ifconfig命令结果中的IP地址;

    7、添加用户bash, testbash, basher以及nologin(其shell为/sbin/nologin);而后找出/etc/passwd文件中用户名同shell名的行;

    "^([^:]+\>) " 锚定行首,冒号除外的第一个单词后进行分组     .* 表示中间跟任意字符。\1$表示分组后在行位进行匹配和行首相同的单词。

    fgrep:不支持正则表达式快速搜索

    在一些几万行,非常庞大的文本里面搜索速度很快。

    常用的文本查看及处理工具命令:wc, cut, sort, uniq, diff, patch

    1.wc    (Word Count)命令的功能为统计指定文件中的字节数、字数、行数,并将统计结果显示输出。

    用法: wc [选项]  file...

    常用选项:

    -c 统计字节数。

    -l 统计行数。

    -w 统计字数。一个字被定义为由空白、跳格或换行字符分隔的字符串。

    2.cut   对文件进过分析,通用指定分隔符,取出我们想要的内容。

    用法:cut  [选项]   file...

    -d  “指定的分隔符”:

    -f   “指定的单个字段,用数字n表示,也可以取出多个字段,n1-n2,也可以取出分散的字段,用逗号隔开,n1,n2...”

    例如:取出/etc/passwd文件第一到三字段内容

    3.sort 文本内容排序命令

    用法:sort  [选项]  file...  

    (多个文件时会内容会组合一起在屏幕输出)

    常用选项:

    -u   去除连续重复且相同的行

    -k  指定第几列进行排序

    -t 指定分隔符进行排序

    -n 按数值大小排序

    -r 逆向排序

    -f  忽略大小写

    例如:对ppp。txt文件第二列和第三列文件进行排序

    4,uniq  报告或忽略重复的行,对相邻的重复的行起作用

    用法:uniq [选项] 文件

    常用选项:

    -c  显示没行重复次数

    -d 仅显示重复的行

    -u  显示没有重复过的行

    5,diff命令  比较两个文件或目录内内容,找到有改动的地方

    用法:diff   [选项]  [旧文件1或目录1]    [新文件2或目录2]

    常用选项:

    -u  以合并的方式显示文件的内容不同

    例如:比较、tmp/functions 和/etc/rc.d/init.d/functions连个文件的不同

    [root@dxlcentOS tmp]# diff -u functions /etc/rc.d/init.d/functions

    --- functions  2017-10-21 17:57:03.359125204 +0800

    +++ /etc/rc.d/init.d/functions  2017-05-03 18:17:50.000000000 +0800

    @@ -681,12 +681,11 @@

    "x$1" = xforce-reload -o \

    "x$1" = xcondrestart ] ; then

    +        systemctl_redirect $0 $1

    exit $?

    -

    -hhhh

    +    fi

    fi

    -strstr "ss(cat /proc/cmdline)" "rc.debug" && set -x

    +strstr "$(cat /proc/cmdline)" "rc.debug" && set -x

    return 0

    -DGDGDGDD

    说明:--- 开头表示旧文件,+++ 开头表示新文件。@@ -681,12 +681,11 @@表示要修改的位置。+表示新文件内容。 -表示旧文件内容

    6. patch命令 向文件打补丁

    补丁文件创建通常由: # diff  /PATH/TO/OLDFILE  /PATH/TO/NEWFILE > /PATH/TO/P_FILE  创建。修改好后就可以向旧文件打补丁。

    打补丁方法:

    方法1:# patch [OPTIONS] -i /PATH/TO/P_FILE /PATH/TO/OLDFILE

    方法2:patch /PATH/TO/OLDFILE < /PATH/TO/P_FILE

    如果要取消补丁做出的更改,恢复旧版本:

    patch   -E    /PATH/TO/OLDFILE < /PATH/TO/P_FILE

    -E :取消打补丁。

    注:以上练习在centos7下进行。

    相关文章

      网友评论

          本文标题:正则表达式和grep用法,及文本查看、处理工具

          本文链接:https://www.haomeiwen.com/subject/dhxtuxtx.html