Linux系统文本处理之awk数组实践
1、统计出/etc/passwd文件中其默认shell为非/sbin/nologin的用户个数,并将用户都显示出来
[root@test ~]#awk -F: '{shells[$NF]++;if($NF == "/sbin/nologin"){print $1,$NF}}END{for(i in shells){print i,shells[i]}}' /etc/passwd bin /sbin/nologin daemon /sbin/nologin adm /sbin/nologin lp /sbin/nologin mail /sbin/nologin uucp /sbin/nologin operator /sbin/nologin games /sbin/nologin gopher /sbin/nologin ftp /sbin/nologin nobody /sbin/nologin dbus /sbin/nologin vcsa /sbin/nologin abrt /sbin/nologin haldaemon /sbin/nologin ntp /sbin/nologin saslauth /sbin/nologin postfix /sbin/nologin sshd /sbin/nologin tcpdump /sbin/nologin redis /sbin/nologin mailnull /sbin/nologin smmsp /sbin/nologin rpc /sbin/nologin rpcuser /sbin/nologin nfsnobody /sbin/nologin apache /sbin/nologin /sbin/shutdown 1 /bin/bash 5 /sbin/nologin 27 /sbin/halt 1 /bin/sync 1 [root@test ~]#
说明:上述命令用到了awk的数组,用":"作为分割符。它处理的流程是这样的,最开始是先声明一个数组名字为shells,用最后一个字段作为数组的索引,第一次shells[$NF]=shells[/bin/bash] ,因为没有定义shells[/bin/bash]的值,所以第一次shells[/bin/bash]的值为空,空就是假,就是0,然后再++ ,++的意思是加1,所以就变成了1,同理第二次是shells[$NF]=shells[/sbin/nologin] 然后++,shells[/sbin/nologin]=1 。因为最开始是没有shells[/bin/bash]和shells[/sbin/nologin],所以++后就都变成了1,处理第三行的时候,shells[$NF]=shells[/sbin/nologin] ,因为第二行处理后,shells[/sbin/nologin]的值就变成了1,所以++后这里就变成了2,以此类推,只要出现shells[/sbin/nologin] 它在处理完后都会加1。我们正是利用了awk数组的这一特性,就统计出“/sbin/nologin” 出现的次数,也就统计出了/etc/passwd下,以冒号作为分隔符,最后一个字段为“/sbin/nologin” 的次数,也就是统计出了系统有这么多用户的默认shell是“/sbin/nologin”。这是统计的流程,其次每处理一行,就判断用冒号分割后的字段,如果最后一个字段为“/sbin/nologin” 就打印出这一行的第一个字段,也就是用户名称。最后我们用for循环去遍历我们之前定义的数组下标,shells表示的是整个数组,这里的i就代表数组中的元素的索引(下标),比如:"/bin/bash","/sbin/nologin"等,再来看看shells[i]=shells[/bin/bash],在上面已经阐述了shells[/bin/bash]是元素出现的次数,所以我们就分别打印了shells里的元素下标和对应出现的次数。NF是awk里的一个变量,它表示以某个分隔符分割后,总共有多少个字段。$NF表示最后一个字段。以上是shell类型为/sbin/nologin的用户,要看非/sbin/nologin的用户在上面的命令上改下判断条件即可。
[qiuhom@test ~]$ echo "Users whose shell type is not /sbin/nologin are:`awk -F: '{shells[$NF]++;if($NF != "/sbin/nologin"){print $1}}' /etc/passwd`" Users whose shell type is not /sbin/nologin are:root sync shutdown halt qiuhom mysql tom jerry [qiuhom@test ~]$
说明:以上命令显示了shell类型为非“/sbin/nologin” 的用户
[qiuhom@test ~]$ awk -F: '{shells[$NF]++}END{for(i in shells){print i,shells[i]}}' /etc/passwd|grep -v "/sbin/nologin"|awk -v total=0 '{total+=$2}END{print "The number of users whose shell type is not /sbin/nologin is:"total}' The number of users whose shell type is not /sbin/nologin is:8 [qiuhom@test ~]$
说明:以上命令显示了shell类型为非“/sbin/nologin”的用户有8个,当然我个人觉得编写个脚本更容易理解,写成命令太长,可读性太差,建议把命令写进脚本里。
[qiuhom@test ~]$ cat checking_users.sh #!/bin/bash user=`awk -F: ' { shells[$NF]++ } { if($NF != "/sbin/nologin") { print $1 } }' /etc/passwd` echo "Users whose shell type is not /sbin/nologin are:$user" user_total=`awk -F: ' { shells[$NF]++ } END{ for(i in shells) { print i,shells[i] } }' /etc/passwd|grep -v "/sbin/nologin"|awk 'BEGIN{total=0}{total+=$2}END{print total}'` echo "The number of users whose shell type is not /sbin/nologin is:$user_total" [qiuhom@test ~]$ sh checking_users.sh Users whose shell type is not /sbin/nologin are:root sync shutdown halt qiuhom mysql tom jerry The number of users whose shell type is not /sbin/nologin is:8 [qiuhom@test ~]$
说明:以上脚本也是利用了上面说到的命令
2、查出用户UID最大值的用户名、UID及shell类型
[root@test ~]#awk -F: 'BEGIN{max=0;user="";shell="";UID=0}{if($3>max){max=$3;user=$1;UID=$3;shell=$NF}}END{print user,UID,shell,max}' /etc/passwd nfsnobody 65534 /sbin/nologin 65534
说明:上面命令的中心思想是这样的,先定义几个初始值,我们把/etc/passwd文件内容,用“:”分割,然后去判断第三个字段,和我们定义的max比较,如果第三个字段的值大于我们的初始化值,那么就把当前第三个字段的值赋给我们定义的变量max,同样,把当前对应的其他值赋给我们定义的变量,这样每处理一行我们定义的变量的值都会相应的发生变化。这样一来max变量最终记录的是处理后最大的值,处理完所有数据,max就是/etc/passwd里面第三个字段最大的值,也就是用户UID最大的那个值,user就是最大uid对应的用户名称,shell就是最大uid对应用户的默认shell类型。
3、统计当前连接本机的每个远程主机IP的连接数,并按从大到小排序
[qiuhom@docker ~]$ss -nt State Recv-Q Send-Q Local Address:Port Peer Address:Port ESTAB 0 0 192.168.0.99:41319 192.168.0.212:54223 ESTAB 0 0 192.168.0.99:41319 192.168.0.232:2187 ESTAB 0 0 192.168.0.99:41319 192.168.0.232:2192 ESTAB 0 0 192.168.0.99:41319 192.168.0.151:42271 ESTAB 0 0 192.168.0.99:41319 192.168.0.212:54224 ESTAB 0 264 192.168.0.99:41319 192.168.0.232:2186 ESTAB 0 0 192.168.0.99:41319 192.168.0.212:54222 ESTAB 0 0 192.168.0.99:41319 192.168.0.232:2190 ESTAB 0 0 192.168.0.99:41319 192.168.0.232:2193 ESTAB 0 0 192.168.0.99:41319 192.168.0.232:2191 [qiuhom@docker ~]$ss -nt|awk -F'[: ]+' '/ESTAB/{ip[$(NF-2)]++}END{for(i in ip){print i,ip[i]}}'|sort -k2 -nr 192.168.0.232 6 192.168.0.212 3 192.168.0.151 1 [qiuhom@docker ~]$
说明:以上命令的核心思想是,先过滤没有用的信息然后取出ip地址,接着利用awk数组来统计每个ip连接的次数,再利用sort来排序。awk用-F指定了多个字符为分隔符,这里需要注意的是通过多个分割符分割后,最后面有一个字段内容为空格,所以我们在统计的时候要用NF-2才是客户端连接本机的ip地址,而不是NF-1,统计的方法也是利用awk数组来实现的,排序是用sort命令,指定第二字段来排序。ss -nt 表示列出已经建立连接的tcp连接信息,其中-n表示不名称解析,-t表示tcp.
4、编写脚本 createuser.sh,实现如下功能:使用一个用户名做为参数,如果 指定参数的用户存在,就显示其存在,否则添加之;显示添加的用户的id号等 信息
[root@docker qiuhom]#cat createuser.sh #!/bin/bash [ $# -ne 1 ] && echo "Usage: $0 USERNAME " && exit [ $UID -ne 0 ] && echo "Run this script with root" && exit if grep -o "^$1" /etc/passwd &>/dev/null;then echo "$1 User Exists" exit else useradd $1 [ $? -eq 0 ] && echo "$1 add succeeful" id $1 fi [root@docker qiuhom]#sh createuser.sh Usage: createuser.sh USERNAME [root@docker qiuhom]#sh createuser.sh a b c Usage: createuser.sh USERNAME [root@docker qiuhom]#su qiuhom [qiuhom@docker ~]$sh createuser.sh f1 Run this script with root [qiuhom@docker ~]$su root 密码: [root@docker qiuhom]#sh createuser.sh root root User Exists [root@docker qiuhom]#sh createuser.sh abc abc add succeeful uid=1003(abc) gid=1003(abc) 组=1003(abc) [root@docker qiuhom]#
5、编写生成脚本基本格式的脚本,包括作者,联系方式,版本,时间,描述等
[qiuhom@docker ~]$ls createuser.sh creatscript.sh f1 tmp.txt xx.sh [qiuhom@docker ~]$cat creatscript.sh #!/bin/bash [ $# -gt 1 ] && echo "Usage:sh $0 FileName" && exit [ $# -eq 0 ] && read -p "please input file name: " filename [ $# -eq 1 ] && filename=$1 -e "$filename" ] && echo "$filename is exists !!!" && exit cat >> $filename << EOF #!/bin/bash ################################################################# #Author: qiuhom #QQ: 467697313 #mail: qiuhom467697313@qq.com #Date: `date +"%F %T"` #FileName: `basename $filename` #URL: https://www.cnblogs.com/qiuhom-1874 #Copyright (C): `date +%Y` All rights #Description: #Version v1.0 ################################################################# EOF vim + $filename [qiuhom@docker ~]$sh creatscript.sh f1 f1 is exists !!! [qiuhom@docker ~]$sh creatscript.sh /etc/fstab /etc/fstab is exists !!! [qiuhom@docker ~]$sh creatscript.sh f2 #!/bin/bash ################################################################# #Author: qiuhom #QQ: 467697313 #mail: qiuhom467697313@qq.com #Date: 2019-10-31 23:24:48 #FileName: f2 #URL: https://www.cnblogs.com/qiuhom-1874 #Copyright (C): 2019 All rights #Description: #Version v1.0 ################################################################# ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ "f2" 13L, 460C