当前位置: 首页>编程语言>正文

linux grep实现原理 linux grep使用

这里总结一下自己在学习时遇到的一些问题与大家分享。

1、显示三个用户root、zmh、tomcat的UID和默认shell

[root@centos7 14:26:19 ~]#egrep '^(root|zmh|tomcat)' /etc/passwd|cut -d: -f1,3,7
root:0:/bin/bash
zmh:1000:/bin/bash
tomcat:1001:/bin/bash

2、统计last命令中以root登录的每个主机IP地址登录次数

[root@centos7 14:32:50 ~]#last | grep '\(^root\)'|grep -o '[[:digit:]]\{1,3\}\.[[:digit:]]\{1,3\}\.[[:digit:]]\{1,3\}\.[[:digit:]]\{1,3\}' | sort |uniq -c
      2 172.20.101.146
      2 172.20.101.162
     60 172.20.101.212
      3 172.20.102.151
      1 172.20.102.209
     30 172.20.95.99
     47 192.168.30.1
      1 192.168.30.101
如果这里还需要按登录次数大小排序就再sort一次。
另外IP地址前三段都是1-3位数字加上.符号构成的,因此可以使用相同规则重复匹配三次再加上第四位地址即可
[root@centos7 15:33:05 ~]#last | grep '\(^root\)'|grep -E -o '([[:digit:]]{1,3}\.){3}[0-9]{1,3}' | sort |uniq -c
      2 172.20.101.146
      2 172.20.101.162
     60 172.20.101.212
      3 172.20.102.151
      1 172.20.102.209
     30 172.20.95.99
     47 192.168.30.1
      1 192.168.30.101

在本人解答这个问题时出现了以下情况:

linux grep实现原理 linux grep使用,linux grep实现原理 linux grep使用_linux grep实现原理,第1张

这样看似已经将结果选择,但是一旦加上-o 只显示命中结果就出现问题了:

linux grep实现原理 linux grep使用,linux grep实现原理 linux grep使用_centos_02,第2张

敲黑板!!一定要弄清楚grep 匹配的是模式,模式,模式!

上图中第一行“192.168”
“192”匹配的是正则中的"[[:digit:].]{1,3}" 它表示数字或者.点字符任意匹配一次到三次,也就是可以匹配的是1-3个纯数字或者1-3个.点字符与数字构成的结果或者是1-3个.点字符。
“192”与“168”之间的.点对应的是正则中的"\."
最后“168”对应的是正则中的“[^[:space:]]{1,3}” 任意非空字符1-3次匹配

在第二行“.30.1”
其中".30"匹配的是"[[:digit:].]{1,3}"。
中间的.点符号匹配的是正则中的"\."
最后“1”匹配的是“[^[:space:]]{1,3}”

因此一个IP地址段被匹配了两次,所以会出现-o选项没有达到我们预期将IPV4地址整体取出的预期

3、显示ifconfig命令结果中所有IPv4地址

在Centos6中:
[root@centos6 ~]# ifconfig | grep -E -o "inet addr:([[:digit:]]{1,3}.){1,3}[0-9]{1,3}" | grep  -o '[^inet addr:].*'
192.168.30.101
172.20.102.151
127.0.0.1
Centos7中:
[root@centos7 16:08:49 ~]#ifconfig | grep -E -o "inet ([[:digit:]]{1,3}.){1,3}[0-9]{1,3}" | grep  -o '[^inet addr:].*'
172.20.95.240
192.168.30.104
127.0.0.1
192.168.122.1
以下是一种通用的过滤模式:
[root@centos7 16:12:16 ~]#ifconfig | grep -o 'inet [^[:space:]]\+' | grep -o '[[:digit:].]\+'
172.20.95.240
192.168.30.104
127.0.0.1
192.168.122.1
如果需要剔除127.0.01再用-v选项过滤一次即可

以上问题当然可以配合其他命令来选出IP,简单的程序链接起来用才是最好的!
[root@centos7 17:11:44 ~]#ifconfig | grep -E '\<inet\>' | tr -s ' ' | cut -d ' ' -f3
192.168.30.104
127.0.0.1
192.168.122.1

4、使用grep 找出磁盘分区使用率最大的数值

[root@centos7 17:17:03 ~]#df | grep '/dev/sd' | egrep -o '[0-9]{1,3}%' | egrep -o '[0-9]{1,3}' | sort -n | tail -1
16

这里先排除临时文件系统已经可能存在的挂载光盘等非磁盘,再使用egrep加正则表达式找出磁盘使用数值再用sort 和tail取最大值。
当然可以配合其他命令更简单些啦:
[root@centos7 17:24:58 ~]#df | grep '/dev/sd' | tr -s ' ' ':' | cut -d: -f5 | tr -d % | sort -n | tail -1
16

5、利用grep查基名和目录名

[root@centos7 17:39:38 ~]#echo  "/etc/rc.d/init.d/" | egrep -o '[^/]+/?$'
init.d/
[root@centos7 17:43:10 ~]#echo  "/etc/rc.d/init.d/" | egrep -o '[^/]+/?$' | egrep -o '.*[^/]\>'
init.d

[root@centos7 17:39:42 ~]#echo  "/etc/rc.d/init.d" | egrep -o '[^/]+/?$'
init.d
[root@centos7 17:39:46 ~]#echo  "/etc/rc.d/init.d" | egrep -o '[^/]+/?$'
以上看出基名最后是否带/斜杠处理比较麻烦,在生产中很可能是不清楚最后是否带斜杠的,而要得到不带斜杠的基名是比较麻烦的,所以还是用basename命令或者用cut做分割吧

6、正则表达式中空行和空白行的表达:

[root@centos7 19:10:15 ~]#cd /data/
[root@centos7 19:10:17 data]#cp /etc/grub2.cfg  grub2
[root@centos7 19:10:45 data]#grep -n '^$' grub2 | cat -A
7:$
10:$
22:$
28:$
30:$
38:$
45:$
59:$
70:$
75:$
86:$
117:$
119:$
122:$
125:$
128:$
134:$
可以看到-n表示行号,后面通过cat -A看到这些行确实都是不包含任何字符的空行
再来看看空白行:
首先往文件中添加一行空白行
[root@centos7 19:11:10 data]#echo "   " >> grub2 
[root@centos7 19:11:29 data]#grep -n '^$' grub2 | cat -A
7:$
10:$
22:$
28:$
30:$
38:$
45:$
59:$
70:$
75:$
86:$
117:$
119:$
122:$
125:$
128:$
134:$
再使用^[[:space:]]$验证
[root@centos7 19:12:54 data]#egrep -n '^[[:space:]]+$' grub2 | cat -A
142:   $

可以看到行号和$符号之间有空格


转载于:https://blog.51cto.com/4081735/2103505


https://www.xamrdz.com/lan/5fr1963836.html

相关文章: