文本处理工具应用练习

练习:

 1 、找出ifconfig 命令结果中本机的IPv4 地址

思路:我们使用ifconfig命令可知,ip地址是在第二行,所以我们先筛选出第二行,

      第二行中的分隔符看起来很混乱,都是不规则的,有一个空格或多个空格的,没有标准

      所以我们最好是建立一个标准分隔,好规范管理,,最后选出ip地址所在的列就可以了 

[root@localhost ~]# ifconfig |head -n2  ==>显示前面输出的前两行,包含有ip地址的那一行
eno16777736: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.18.18.65  netmask 255.255.255.0  broadcast 172.18.18.255
[root@localhost ~]# ifconfig |head -n2|tail -n1   ==>同上原理,显示只包含ip地址的行
        inet 172.18.18.65  netmask 255.255.255.0  broadcast 172.18.18.255
[root@localhost ~]# ifconfig |head -n2|tail -n1|tr " " ":"  ==>建立标准分隔符,将默认分隔符“ ”改为容易识别的":"
::::::::inet:172.18.18.65::netmask:255.255.255.0::broadcast:172.18.18.255
[root@localhost ~]# ifconfig |head -n2|tail -n1|tr " " ":"|tr -s ":"  ==>进一步简化,删除所有重复的字符以单独一个字符表示,使之更容易识别
:inet:172.18.18.65:netmask:255.255.255.0:broadcast:172.18.18.255
[root@localhost ~]# ifconfig |head -n2|tail -n1|tr " " ":"|tr -s ":"|cut -d: -f3  ==>以“:”为分隔符,选择第三列就是我们要选的ip地址
172.18.18.65
[root@localhost ~]#

 2 、查出分区空间使用率的最大百分比值

思路:和上面类似,以下输出分隔符混乱,看都看晕了,所以一样的要建立一个标准分隔符,好规范管理,取出使用率列后,

      按照数字大小排序,取最大的那个一行就可以得到最大空间使用率的百分比值了 ,如下

[root@localhost ~]# df
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/sda2       41922560  812752  41109808   2% /
devtmpfs          486268       0    486268   0% /dev
tmpfs             500664       0    500664   0% /dev/shm
tmpfs             500664    6832    493832   2% /run
tmpfs             500664       0    500664   0% /sys/fs/cgroup
/dev/sda3       20961280 3269760  17691520  16% /usr
/dev/sda1         496300  140252    356048  29% /boot
tmpfs             100136       0    100136   0% /run/user/0
[root@localhost ~]# df|tr " " ":"    ==>建立标准分隔符,将默认分隔符“ ”改为容易识别的":"
Filesystem:::::1K-blocks::::Used:Available:Use%:Mounted:on
/dev/sda2:::::::41922560::812752::41109808:::2%:/
devtmpfs::::::::::486268:::::::0::::486268:::0%:/dev
tmpfs:::::::::::::500664:::::::0::::500664:::0%:/dev/shm
tmpfs:::::::::::::500664::::6832::::493832:::2%:/run
tmpfs:::::::::::::500664:::::::0::::500664:::0%:/sys/fs/cgroup
/dev/sda3:::::::20961280:3269760::17691520::16%:/usr
/dev/sda1:::::::::496300::140252::::356048::29%:/boot
tmpfs:::::::::::::100136:::::::0::::100136:::0%:/run/user/0
[root@localhost ~]# df|tr " " ":"|tr -s ":"   ==>进一步简化,删除所有重复的字符以单独一个字符表示,使之更容易识别
Filesystem:1K-blocks:Used:Available:Use%:Mounted:on
/dev/sda2:41922560:812752:41109808:2%:/
devtmpfs:486268:0:486268:0%:/dev
tmpfs:500664:0:500664:0%:/dev/shm
tmpfs:500664:6832:493832:2%:/run
tmpfs:500664:0:500664:0%:/sys/fs/cgroup
/dev/sda3:20961280:3269760:17691520:16%:/usr
/dev/sda1:496300:140252:356048:29%:/boot
tmpfs:100136:0:100136:0%:/run/user/0
[root@localhost ~]# df|tr " " ":"|tr -s ":"|cut -d: -f5  ==>以“:”为分隔符,第5列就是空间使用率
Use%
2%
0%
0%
2%
0%
16%
29%
0%
[root@localhost ~]# df|tr " " ":"|tr -s ":"|cut -d: -f5|sort -rn  ==>将空间使用率案数字大小排序
29%
16%
2%
2%
Use%
0%
0%
0%
0%
[root@localhost ~]# df|tr " " ":"|tr -s ":"|cut -d: -f5|sort -rn|head -n1   ==>只显示第一行即空间使用率最大的一行
29%
[root@localhost ~]# df|tr " " ":"|tr -s ":"|cut -d: -f5|sort -rn|head -n1|tr -d "%"  ==>去掉“%”,得到分区空间使用率的最大百分比值
29

 3 、查出用户UID 最大值的用户名、UID 及shell 类型

思路:查看/etc/passwd文件可知,文件内容是使用“:”做分隔符的,开心啊..,我们要查看UID最大的的用户信息,

      所以要以第三行来进行数字大小排序,然后选出最大的那一行,在根据分隔符选出自己想要的那几列

[root@localhost ~]# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
...............................             ==>文件太长,就不全部显示了,用省略号代替
basher:x:4330:4335::/home/basher:/bin/bash
nologin:x:4331:4336::/home/nologin:/bin/nologin
wang:x:4332:4337::/home/wang:/bin/bash
systemd-network:x:998:996:systemd Network Management:/:/sbin/nologin
systemd-bus-proxy:x:999:997:systemd Bus Proxy:/:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
[root@localhost ~]# cat /etc/passwd|sort -t: -k3 -n   ==>以“:”为分隔符,取第三列进行数字大小排序
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
.................                              ==>文件太长,就不全部显示了,用省略号代替
tom:x:4327:4331::/home/tom:/bin/bash
bash:x:4328:4333::/home/bash:/bin/bash
testbash:x:4329:4334::/home/testbash:/bin/bash
basher:x:4330:4335::/home/basher:/bin/bash
nologin:x:4331:4336::/home/nologin:/bin/nologin
wang:x:4332:4337::/home/wang:/bin/bash
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
[root@localhost ~]# cat /etc/passwd|sort -t: -k3 -n|tail -n1    ==>取出UID值最大的行
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
[root@localhost ~]# cat /etc/passwd|sort -t: -k3 -n|tail -n1|cut -d: -f1,3,7    ==>以“:”为分隔符,选出用户名,UID值,shell类型那几列,自己数啊
nfsnobody:65534:/sbin/nologin
[root@localhost ~]#

 4 、查出/tmp 的权限,以数字方式显示

思路:开始以为是将rwx换成对应的421,要是这么简单就好了,此题要显示的结果是777这样的

      stat命令,查看时间戳的命令,此命令可以以数字方式显示文件的权限,这样就有方向了

      首先一样的要先取出含有数字权限的行,然后灵活运用分隔符来取出数字权限,具体看下面操作

[root@localhost ~]# stat /tmp
  File: ‘/tmp’
  Size: 4096      	Blocks: 8          IO Block: 4096   directory
Device: 802h/2050d	Inode: 133         Links: 14
Access: (1777/drwxrwxrwt)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2016-07-29 10:26:25.542877847 +0800
Modify: 2016-08-06 10:27:25.572103012 +0800
Change: 2016-08-06 10:27:25.572103012 +0800
 Birth: -
[root@localhost ~]# stat /tmp|head -n4  ==>显示前面输出的前4行,包含有数字权限的那一行
  File: ‘/tmp’
  Size: 4096      	Blocks: 8          IO Block: 4096   directory
Device: 802h/2050d	Inode: 133         Links: 14
Access: (1777/drwxrwxrwt)  Uid: (    0/    root)   Gid: (    0/    root)
[root@localhost ~]# stat /tmp|head -n4|tail -n1     ==>显示包含数字权限的行
Access: (1777/drwxrwxrwt)  Uid: (    0/    root)   Gid: (    0/    root)
[root@localhost ~]# stat /tmp|head -n4|tail -n1|cut -d"/" -f1    ==>以“/”为分割符,取第一行,结果如下
Access: (1777
[root@localhost ~]# stat /tmp|head -n4|tail -n1|cut -d"/" -f1|cut -d"(" -f2   ==>以“(”为分隔符,取第二行,结果如下
1777

因为stat命令显示内容格式一样,所以以上命令适用于任何文件,通用型

blob.png

当然方法不是唯一的,肯定还有别的方法表示,

 5 、统计当前连接本机的每个远程主机IP 的连接数,并按从大到小排序

思路:netstat -nt是查看远程主机ip的,因为远程主机ip不是固定数量的,这里会提前用到grep筛选,grep后面也有,

      和前面几题差不多,建立标准分隔符,然后选出想要的列即可,然后排序,然后显示重复的行出现的次数,

      再排序,结果就出现了,如下

[root@localhost ~]# netstat -nt
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address               Foreign Address             State      
tcp        0      0 172.18.18.51:22             172.18.18.206:52175         ESTABLISHED 
tcp        0    192 172.18.18.51:22             172.18.18.206:58442         ESTABLISHED 
tcp        0      0 172.18.18.51:22             172.18.18.65:41764          ESTABLISHED 
tcp        0      0 172.18.18.51:22             172.18.18.65:41765          ESTABLISHED 
tcp        0      0 172.18.18.51:22             172.18.18.206:52181         ESTABLISHED 
[root@localhost ~]# netstat -nt|grep tcp                                                   ==>显示远程主机ip的信息
tcp        0      0 172.18.18.51:22             172.18.18.206:52175         ESTABLISHED 
tcp        0     64 172.18.18.51:22             172.18.18.206:58442         ESTABLISHED 
tcp        0      0 172.18.18.51:22             172.18.18.65:41764          ESTABLISHED 
tcp        0      0 172.18.18.51:22             172.18.18.65:41765          ESTABLISHED 
tcp        0      0 172.18.18.51:22             172.18.18.206:52181         ESTABLISHED 
[root@localhost ~]# netstat -nt|grep tcp|tr " " ":"                                      ==>建立标准分隔符,将默认分隔符“ ”改为容易识别的":"
tcp::::::::0::::::0:172.18.18.51:22:::::::::::::172.18.18.206:52175:::::::::ESTABLISHED:
tcp::::::::0:::::64:172.18.18.51:22:::::::::::::172.18.18.206:58442:::::::::ESTABLISHED:
tcp::::::::0::::::0:172.18.18.51:22:::::::::::::172.18.18.65:41764::::::::::ESTABLISHED:
tcp::::::::0::::::0:172.18.18.51:22:::::::::::::172.18.18.65:41765::::::::::ESTABLISHED:
tcp::::::::0::::::0:172.18.18.51:22:::::::::::::172.18.18.206:52181:::::::::ESTABLISHED:
[root@localhost ~]# netstat -nt|grep tcp|tr " " ":"|tr -s ":"                           ==>进一步简化,删除所有重复的字符以单独一个字符表示,使之更容易识别
tcp:0:0:172.18.18.51:22:172.18.18.206:52175:ESTABLISHED:
tcp:0:64:172.18.18.51:22:172.18.18.206:58442:ESTABLISHED:
tcp:0:0:172.18.18.51:22:172.18.18.65:41764:ESTABLISHED:
tcp:0:0:172.18.18.51:22:172.18.18.65:41765:ESTABLISHED:
tcp:0:0:172.18.18.51:22:172.18.18.206:52181:ESTABLISHED:
[root@localhost ~]# netstat -nt|grep tcp|tr " " ":"|tr -s ":"|cut -d: -f6   ==>以“:”为分隔符,选择远程主机ip的列
172.18.18.206
172.18.18.206
172.18.18.65
172.18.18.65
172.18.18.206
[root@localhost ~]# netstat -nt|grep tcp|tr " " ":"|tr -s ":"|cut -d: -f6|sort  ==>排序,将相同的行整理到一起(这一步很重要)
172.18.18.206
172.18.18.206
172.18.18.206
172.18.18.65
172.18.18.65
[root@localhost ~]# netstat -nt|grep tcp|tr " " ":"|tr -s ":"|cut -d: -f6|sort |uniq -c ==>显示重复行出现的次数
      3 172.18.18.206
      2 172.18.18.65
[root@localhost ~]# netstat -nt|grep tcp|tr " " ":"|tr -s ":"|cut -d: -f6|sort |uniq -c|sort -rn ==>按数字从大到小排序
      3 172.18.18.206
      2 172.18.18.65

上面有个sort指令特别提示很重要,那我们来看看如果没有这一步会如何

[root@localhost ~]# netstat -nt|grep tcp|tr " " ":"|tr -s ":"|cut -d: -f6|uniq -c|sort -rn
      2 172.18.18.65
      2 172.18.18.206
      1 172.18.18.206

显示的结果完全不同,这是因为uniq指令定义重复行是连续且完全相同的行,

所以尽管第二行和第三行是完全的行,但是因为不是连续的,uniq并没有把它们显示为重复行,

而是分开显示了,用实例来说明吧

[root@localhost ~]# cat a
aaaaaa
bbbbbb
aaaaaa
aaaaaa
aaaaaa
[root@localhost ~]# cat a|uniq -c  ==>a文件的第一行没有显示为重复行,只有最下面连续的三行显示为重复行
      1 aaaaaa 
      1 bbbbbb
      3 aaaaaa
[root@localhost ~]# cat a|sort    ==>把a文件排序后,所以的aaaaa都连续显示了 
aaaaaa
aaaaaa
aaaaaa
aaaaaa
bbbbbb
[root@localhost ~]# cat a|sort|uniq -c  ==>再看,重复行变为四行了
      4 aaaaaa
      1 bbbbbb

正则表达式练习:

1 、显示/proc/meminfo 文件中以大小s 开头的行;( 要求:使用两种方式)

思路:要求开头是大小写s的,所以要锚定行首,开始是s即可,后面是什么无所谓,就是指任意字符

指令如下:

grep -i "^s.*"  /proc/meminfo 
grep "^[sS].*"  /proc/meminfo 
[root@localhost ~]# grep -e "^s.*" -e "^S.*"  /proc/meminfo

blob.png

blob.png

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

思路:我们找出一/bin/bash结尾的行然后取反就可以了 ,因为是结尾,所以要锚定行尾如下:

[root@localhost ~]# grep  "/bin/bash$" /etc/passwd   ==>以/bin/bash结尾的行
[root@localhost ~]# grep -v "/bin/bash$" /etc/passwd   ==>使用-v选项取反,内容太多,就不全部显示了
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
.......

 3 、显示用户rpc 默认的shell 程序

思路:用户rpc,所以锚定单词,然后以分隔符取出shell所在的列

[root@localhost ~]# grep "\<rpc\>" /etc/passwd          ==>匹配用户rpc所在的行
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
[root@localhost ~]# grep "\<rpc\>" /etc/passwd|cut -d: -f7   ==>以“:”为分隔符,取出sheel所在的列
/sbin/nologin
[root@localhost ~]#

 4 、找出/etc/passwd 中的两位或三位数

思路:两位或三位数,所以是锚定单词,数字出现两次到三次

指令:

grep "\<[0-9]\{2,3\}\>" /etc/passwd

blob.png

5 、显示/etc/grub2.cfg 文件中,至少以一个空白字符开头的且后面存非空白字符的行

以空白字符开头,即要使用行首锚定,至少一个,后面存在非空白字符,如下:

cat /etc/grub2.cfg |grep "^[[:space:]]\+[^[:space:]]"

blob.png

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

思路:看到结尾就要行尾锚定,LISTEN后面跟任意个空白字符

指令:

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

blob.png

 7 、添加用户bash 、testbash 、basher 以及nologin( 其shell为 为

/sbin/nologin), 而后找出/etc/passwd 文件中用户名同shell名 名

的行

思路:用户和shell同名,所以要锚地单词,且要锚定行首,因为同名,所以要用到后向引用,

       shell在最后,所以引用的时候要锚定行尾

指令:

cat /etc/passwd |grep "^\<\(.*\)\>.*\1$"

blob.png

以上指令可以理解为:前面括号里面出现在行首的任意单词,都要在行尾出现一次,\就是后向引用,

                    引用前面出现的单词,而两个相同单词中间可以出现任意字符(即是指的后面一个.*) 

                    行首单词a(^\<\(.*\)\>) 任意字符(.*) 行尾单词a(\1$)

扩展正则表达式练习

1 、显示当前系统root 、mage 或wang 用户的UID 和默认shell

(root|mage|wang)表示或关系,因为是特指用户所有行首锚定,词尾锚定

指令:

egrep "^(root|mage|wang)\>" /etc/passwd

blob.png

 2 、找出/etc/rc.d/init.d/functions 文件中行首为某单词(包括下划线) 后面跟一个小括号的行

思路:行首锚定,单词锚定,单词中包含数字字母下划线至少出现一次,后面括号,

注意:扩展正则表达式和基本正则表达式元字符使用时要差异,最明显的是转义符,谨记!!!!!!!

blob.png

 3 、使用egrep 取出/etc/rc.d/init.d/functions 中其基名

说明:基名即使functions

思路:基名肯定是在行尾,所有锚定行尾,且不能有“/”

指令:

echo /etc/rc.d/init.d/functions|egrep  -o "[^/]+$"

blob.png

 4 、使用egrep 取出上面路径的目录名

   本来想做上面也一题的,莫名其妙把这题搞出来了,也是醉了

指令:

echo /etc/rc.d/init.d/functions|egrep -o "/.*/"

blob.png

 5 、统计以root 身份登录的每个远程主机IP 地址的登录次数

指令:

last |egrep "root"|egrep -o  "(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])"|sort|uniq -c|sort -n

blob.png

6 、利用扩展正则表达式分别表示0-9 、10-99 、100-199、  200-249 、250-255

 说明:上面一题已经显示过了

egrep -o  "(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])"

 7 、显示ifconfig 命令结果中所有IPv4

  说明: 第五题方法也可解决此问题

ifconfig |egrep -o  "(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])"

blob.png

课后习题

1、统计/etc/init.d/functions 文件中每个单词出现的次数,并按频率从高到低显示

cat /etc/init.d/functions |grep -o "\<[[:alnum:]]*\>"|sort|uniq -c|sort -n

blob.png

2、正则表达式表示身份证号

   验证我的身份证号码成功了,但是感觉有问题

echo 420117198912073577 | egrep "(^[1-9][0-9]{16}[[:digit:]xX]$)|^([1-9][0-9]{14})$"
echo 420117198912073577 | egrep "(\<[1-9][0-9]{16}[[:digit:]xX]\>)|\<([1-9][0-9]{14})\>"

blob.png

3、正则表达式表示手机号

手机号码11位,开头固定为1,第二位我知道的是3,5,8,要是不对可以再换,后面9位数字

echo 18922718172|egrep "^1[358][0-9]{9}$"

blob.png

4、正则表达式表示邮箱

   我不太了解邮箱的必要条件,所以可能有漏掉一些字符,,以下我自己的邮箱是符合的…..

echo 0811_7...64@126.com |egrep "[[:alnum:]_.]+@[[:alnum:]_.]+\.com"

blob.png

5、正则表达式表示QQ号

echo 381147864|egrep "\<[1-9][0-9]{4,}"

blob.png

以上这些题目希望老师能最好在能够在上课的时候稍微讲一下 !!

原创文章,作者:qiuwei,如若转载,请注明出处:http://www.178linux.com/29972