[svc]linux正则实战(grep/sed/awk)

企业实战: 过滤ip

过滤出第二行的 192.168.2.11.

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.2.11  netmask 255.255.255.0  broadcast 192.168.2.255
        ether 00:0c:29:41:85:df  txqueuelen 1000  (Ethernet)
        RX packets 17934  bytes 9131091 (8.7 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 13981  bytes 2627375 (2.5 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

深入浅出linux三剑客之sed必杀技一例
深入浅出linux三剑客之awk必杀技一例

方法1: 使用sed替换为空(删除首尾多余)

- 先打印第二列
[root@n1 ~]# ifconfig eth0|sed -n '2p'                                        
        inet 192.168.2.11  netmask 255.255.255.0  broadcast 192.168.2.255

- 删除前面多余的
[root@n1 ~]# ifconfig eth0|sed -n '2p'|sed 's#^.*inet ##g'                    
192.168.2.11  netmask 255.255.255.0  broadcast 192.168.2.255

- 删除后面多余的,得到结果
[root@n1 ~]# ifconfig eth0|sed -n '2p'|sed 's#^.*inet ##g'|sed 's#net.*$##g'
192.168.2.11  <==这里有2个空格


[root@n1 ~]# ifconfig eth0|sed -n '2p'|sed 's#^.*inet ##g'|sed 's#  net.*$##g'
192.168.2.11


方法2: 使用sed行号指定行

- 取消默认输出
[root@n1 ~]# ifconfig eth0|sed -n 's#^.*inet ##g'

- 仅输出匹配到的内容(可能有多行)
[root@n1 ~]# ifconfig eth0|sed -n 's#^.*inet ##gp'
192.168.2.11  netmask 255.255.255.0  broadcast 192.168.2.255

- 仅输出第二行
[root@n1 ~]# ifconfig eth0|sed -n '2s#^.*inet ##gp'
192.168.2.11  netmask 255.255.255.0  broadcast 192.168.2.255

- 删除结尾多余的(-n 取消默认输出)
[root@n1 ~]# ifconfig eth0|sed -n '2s#^.*inet ##gp'|sed -n 's#  netmask.*$##g'

- 删除结尾多余的,并打印结果
[root@n1 ~]# ifconfig eth0|sed -n '2s#^.*inet ##gp'|sed -n 's#  netmask.*$##gp'
192.168.2.11

另一种理解

[root@n1 ~]# ifconfig eth0|sed -n '2p'                                        
        inet 192.168.2.11  netmask 255.255.255.0  broadcast 192.168.2.255

[root@n1 ~]# ifconfig eth0|sed -n '2s#^.*inet ##gp'
192.168.2.11  netmask 255.255.255.0  broadcast 192.168.2.255

方法3: sed的后向引用: 最佳方案

理解sed的后向引用

sed  's#()()#\1\2#g' #\1引用第一个括号内容 \2引用第二个括号内容

注意: 如果正则里有了()等,需要转义的字符,特别多,且麻烦. 就需要加上-r参数了. 加上后,无需顾忌正则表达式里的特殊字符.
  • 匹配前面的

  • 匹配后面的

  • 中间括号匹配 maotai

过滤ip:

有空格

- 干掉空格
[root@n1 ~]# ifconfig eth0|sed -nr 's#^.*inet (.*)  net.*$#\1#gp'
192.168.2.11

另一种思路: 直接匹配到ip

grep过滤ip和邮箱
这种写的比较烦

这种简化一下

[root@n1 ~]# ifconfig eth0|sed -nr '2s#^.*inet ([0-9]{,3}.[0-9]{,3}.[0-9]{,3}.[0-9]{,3})  net.*$#\1#gp'
192.168.2.11

- 简化写
[root@n1 ~]# ifconfig eth0|sed -nr '2s#^.*inet (([0-9]{,3}.){3}[0-9]{,3})  net.*$#\1#gp'
192.168.2.11

企业案例: 取出stat文件的权限644

[root@n1 ~]# stat a.log 
  File: ‘a.log’
  Size: 19        	Blocks: 8          IO Block: 4096   regular file
Device: fd00h/64768d	Inode: 68061539    Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2018-03-04 11:30:25.072372498 +0800
Modify: 2018-03-04 11:30:23.781372221 +0800
Change: 2018-03-04 11:30:23.781372221 +0800
[root@n1 ~]# stat a.log |sed -nr '4s#^.*\(0(.*)\/-.*$#\1#gp'
644

另一个企业实例: 将maotai.txt文件的权限位rw-r--r-- #将这个转为644打印.

深入浅出linux三剑客之sed必杀技一例
深入浅出linux三剑客之awk必杀技一例

方法1: 使用awk过滤列,使用tr替换后,awk求和打印.

[root@n1 ~]# ll maotai.txt 
-rw-r--r-- 1 root root 292 Mar  3 21:28 maotai.txt

rw-r--r-- #将这个转为644打印.
r 4表示
w 2表示
x 1表示
- 0表示

tr命令:

[root@n1 ~]# echo 'mm'|tr 'm' 'Z'
ZZ

[root@n1 ~]# echo "HELLO MAOTAI"|tr 'A-Z' 'a-z'
hello maotai
- 将权限位替换为数字
[root@n1 ~]# ll maotai.txt|awk -F ' ' '{print $1}'|tr 'rwx-' '4210'
0420400400

- 不分隔求每3项的和
[root@n1 ~]# ll maotai.txt|awk -F ' ' '{print $1}'|tr 'rwx-' '4210'|awk -F '' '{print $2+$3+$4""$5+$6+$7""$8+$9+$10}'
644

方法2: 使用cut过滤列,使用tr替换后,awk求和打印.

[root@n1 ~]# ll maotai.txt|cut -c2-10|tr 'rwx-' '4210'
420400400

方法3: 巧用stat命令

[root@n1 ~]# stat maotai.txt |sed -nr '4s#^.*\(0(.*)/-.*$#\1#gp'
644

方法4: 使用stat+awk过滤

- 先过滤出列
[root@n1 ~]# stat maotai.txt |awk -F '[0/]' '{print $2}'

96   regular file

644
18-
18-
18-

- 过滤第四行的某一列
[root@n1 ~]# stat maotai.txt |awk -F '[0/]' 'NR==4 {print $2}'
644

方法5: 使用stat自带参数

[root@n1 ~]# stat -c %a maotai.txt 
644

方法6: grep正则过滤

[root@n1 ~]# stat maotai.txt |grep -Eo "^.*/-"
Access: (0644/-

[root@n1 ~]# stat maotai.txt |grep -Eo "^.*/-"|grep -o "[4-6]*"
644
三点思路小结:
1.通过stat输出包含目录的内容
2.通过head tail sed awk grep定位到单行        =>取行
3.通过cut awk等设置分隔符取出所需的段内容 =>取列

4.当结果中包含了我们想要的东西时候,该命令可能有参数可以直接取出结果

企业实例: 用sed替换/etc/passwd的首尾两列

思路: ()()() 第一列,中间的,最后一列, 使用sed的后向引用.

[root@n1 ~]# sed -nr '1s#([^:]+)(:.*:)(/.*$)#\3\2\1#gp' /etc/passwd
/bin/bash:x:0:0:root:/root:root
posted @ 2018-03-04 11:12  _毛台  阅读(588)  评论(0编辑  收藏  举报