概念
正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(英语: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文件中某单词后面跟一个小括号的行;
[root@dxlcentOS ~]# egrep -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下进行。
本文来自投稿,不代表Linux运维部落立场,如若转载,请注明出处:http://www.178linux.com/87978