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 
原文地址:https://www.cnblogs.com/qiuhom-1874/p/11774545.html