17 正则表达式及作业
因为正则表达式类型较多且比较重要,因此单独拿出一篇进行陈述。
正则表达式是各种文本处理工具的基础,也是shell编程必须牢牢掌握的知识,其重要性不言而喻。
一、杂项知识整理
1、一个[:space:]包括一个tab。
2、区分好文件名通配(globing)和文件内容通配(正则表达式)。
在文件名通配中[a-c]是指aAbBc,而正则表达式中是abc。
3、正则表达式中-w或锚定的时候的单词中也包括数字,不包括特殊符号。
4、grep选项中-e表示逻辑或,但是没有与的选项,功能可用管道等实现。
5、basename取目录中的基名。给定路径:
[root@localhost test]# basename /etc/init.d/functions functions
basename [pathname] [suffix]
basename [string] [suffix]
suffix为后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉。
[root@localhost test]# basename /etc/init.d/functions.txt .txt functions
6、正则表达式的算法与扩展正则表达式不同,元字符分类:字符匹配,匹配次数,位置锚定,分组
二、详细命令及事例
1、正则表达式grep:文本搜索工具,根据用户指定的“模式PATTERN”对目标文本逐行进行匹配检查,打印匹配到的行。
PATTERN:由正则表达式字符及文本字符所编写的过滤条件。
2、grep命令选项:–color=auto:默认别名
-v 显示不能被模式匹配到的行
-i 忽略字符大小写
-n 显示匹配到的行在原文件中的行号
-q 静默模式,不输出任何信息
-o 仅显示匹配到的字符串
-c 统计匹配的行数
-A # :after,后#行
-B # :before,前#行
-C # :前后#行
-e 实现多个选项之间的逻辑或
grep -e “aaa” -e “bbb” FILE
-w 整行匹配整个单词
-E 支持扩展正则表达式
3、字符匹配:. 匹配单个任意字符
[] 匹配指定范围内的任意单个字符
[^] 匹配指定范围外的任意单个字符
[:digit:]任意数字 [:lower:]任意小写字母 [:upper:]任意大写字母 [:alpha:]任意字母 [:alnum:]所有字母及数字 [:space:]所有空格,包括tab [:punct:]所有特殊字符
4、匹配次数:* 匹配前面的字符任意次,包括0次
.* 任意长度的任意字符
\? 匹配其前面的字符0或1次
\+ 匹配其前面的字符至少一次
\{m\}匹配前面的字符m次,准确数值
\{m,n\} 匹配其前面的字符至少m次,至多n次
\{,n\} 匹配前面的字符至多n次
\{m,\} 匹配前面的字符至少m次
位置锚定:^ 行首锚定,用于模式的最左侧
$ 行尾锚定,用于模式的最右侧
^PATTERN$ 用于模式匹配整行
^$ 空行
^[[:space:]]*$ 空白行
\<或\b 词首锚定,用于单词模式的左侧
\>或\b 词尾锚定,用于单词模式的右侧,限定某个单词。
\<PATTERN\> 匹配整个单词、
5、分组:
\(\) 将一个或多个字符捆绑在一起,当做一个整体进行处理,如\(root\)+
分组括号中的模式匹配到的内容会被正则表达式引擎记录在内部的变量中,这些变量的命名方式为:\1,\2,\3,…
\1:从左侧开始,第一个左括号以及与之匹配的右括号之间的模式所匹配到的字符:
\(string\+\(string2\)*\)
\1:string1\+\(string2\)*
\2: string2
第几个变量就是第几个左括号以及与其组合右括号中间的内容。若\(\).*\1则是一行之中同时满足两个模式,也就是调用前一个分组内容进行匹配。
6、扩展正则表达式:grep -E 与 egrep 相同;不同之处:
* 匹配前面字符任意次
? 匹配前面字符零次或者一次
+ 匹配前面字符一次或者多次
{m} 匹配前面字符m次
{m,n} 匹配前面的字符至少m次,至多n次
( ) 分组
或者:a|b
区别在于扩展正则表达式多了或者的逻辑模式,次数匹配和分组中没有\。其他相同。
三、作业及练习
1、IP地址:\<(1|2)[[:digit:]]{1,2}.[0-9]{1,3}.[0-9]{1,3}.[[:digit:]]{1,3}\>
2、手机号:\<1(3|4|5|6|7|8)[[:digit:]]\{9\}\>
3、身份证号:\<[[:digit:]]\{6\}(1|2){0|9}[[:digit:]]\{2\}(0|1)[[:digit:]][0-3][[:digit:]]\{4\}(X|[[:digit:]])\>
4、邮箱:\<[[:alpha:]]\{1,20\}@[[:alpha:]]\+.com\>
5、显示/proc/meminfo文件中以大小写s开头的行:
[root@localhost ~]# grep -i "\<s" /proc/meminfo SwapCached: 0 kB SwapTotal: 4050936 kB SwapFree: 4050936 kB Shmem: 6796 kB Slab: 87204 kB SReclaimable: 43816 kB SUnreclaim: 43388 kB [root@localhost ~]# grep -E "\<(s|S)" /proc/meminfo SwapCached: 0 kB SwapTotal: 4050936 kB SwapFree: 4050936 kB Shmem: 6796 kB Slab: 87212 kB SReclaimable: 43848 kB SUnreclaim: 43364 kB
6、显示/etc/passwd文件中不以/bin/bash结尾的行
[root@localhost ~]# grep -v "/bin/bash\>" /etc/passwd
7、显示用户rpc默认的shell程序:
[root@centos68 ~]# grep "\<rpc\>" /etc/passwd rpc:x:32:32:Rpcbind Daemon:/var/cache/rpcbind:/sbin/nologin
8、找出/etc/passwd中的两位或者三位数
[root@localhost ~]# grep -o "\<[[:digit:]]\{2,3\}\>" /etc/passwd
9、显示/etc/grub2.cfg文件中,至少以一个空白字符开头的且后面存在非空白字符的行:
grep "^[[:space:]]\+.*[^[:space:]].*" /etc/grub2.cfg
10、找出“netstat -tan”命令的结果中以'LINSTEN'后跟0、1或多个空白字符结尾的行:
[root@localhost ~]# netstat -tan | grep "\<LISTEN\>[[:space:]]*$" tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN tcp6 0 0 :::22 :::* LISTEN tcp6 0 0 ::1:25 :::* LISTEN
11、添加用户bash,testbash、basher以及nologin(shell类型为nologin),而后找出/etc/passwd文件中用户名同shell名的行
[root@localhost ~]# grep "^\<\(.*\)\>.*\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:2231:2231::/home/bash:/bin/bash nologin:x:2233:2233::/home/nologin:/sbin/nologin
12、显示当前系统root,mage或wang用户的UID和默认shell:
[root@localhost ~]# egrep "^(root|wang)" /etc/passwd root:x:0:0:root:/root:/bin/bash wang:x:2234:2234::/home/wang:/bin/bash
13、找出/etc/rc.d/init.d/functions文件中行首为某单词包括下划线,后面跟一个小括号的行:
[root@localhost ~]# egrep "^([[:alpha:]_])+\(\).*" /etc/rc.d/init.d/functions
14、使用egrep取出/etc/rc.d/init.d/functions中其基名:
[root@localhost ~]# echo "/etc/rc.d/init.d/functions" | egrep -o "[^/]+$" functions
15、使用egrep取出上面路径的目录名:
[root@localhost ~]# echo "/etc/rc.d/init.d/functions" | egrep -o "^.*/" /etc/rc.d/init.d/
16、统计以root身份登录的每个远程主机IP地址的登录次数。
[root@localhost ~]# last | grep root | egrep -o "[[:digit:]]+.[[:digit:]]+.[[:digit:]]+.[[:digit: ]]+" | sort | uniq -c 12 10.1.250.66 1 10.1.255.1 1 10.1.49.49 48 172.18.16.71 1 192.168.1.111
18、显示ifconfig命令结果中所有的IPv4地址。
[root@localhost ~]# ifconfig | egrep -o "\<(1|2)[[:digit:]]{1,2}.[0-9]{1,3}.[0-9]{1,3}.[[:digit:] ]{1,3}\>"172.18.16.49 255.255.255.0 172.18.16.255 29:51:36:20 127.0.0.1 255.0.0.0
此处要是用分组来匹配则为:
[root@localhost ~]# ifconfig | egrep -o "\<(1|2)[[:digit:]]{1,2}.([0-9]{1,3}).\2.[[:digit:]]{1,3} \>"255.255.255.0 127.0.0.1 255.0.0.0
因为分组的变量匹配只找行内两个完全相同的PATTERN值,即使是模糊匹配也必须完全相同才能符合,因此此处IP中间两个值为相同。注意:变量是找第一个左括号开始的地方,而不管括号作用是什么。
原创文章,作者:SilencePavilion,如若转载,请注明出处:http://www.178linux.com/29246