• awk处理/etc/passwd文件


    前言

    awk 是 linux 环境下的一个强大的编程工具,用于对文本和数据进行处理。数据可以来自标准输入、一个或多个文件,或其它命令的输出。同时它支持用户自定义函数和动态正则表达式等先进功能,可以被作为一种编程语言,可以很方便的在命令行中使用,但更多是在脚本来使用,为了熟悉这个命令,我们可以用它来尝试处理 /etc/passwd 文件学习一下常见用法。

    awk处理流程

    awk 这个名字来源于它的三个作者姓氏的第一个字母,分别是Alfred AhoBrian KernighanPeter Weinberger,常用的版本是 gawk, 它是awk的GNU版本,提供了Bell实验室和GNU的一些扩展。

    awk 工作流程可分为三个部分:

    • 读输入文件之前执行的代码段(GEGIN块,由BEGIN关键字标识,可选)
    • 主循环执行输入文件的代码段(BODY块,可选)
    • 读输入文件之后的代码段(END块,由END关键字标识,可选)

    命令结构:

    awk 'BEGIN{ commands } pattern{ commands } END{ commands }'
    
    • 1

    开始块(BEGIN)

    BEGIN {awk-commands}
    
    • 1

    开始块部分是可选的,可以没有开始块部分,如果存在必须以 BEGIN 开头

    开始块就是在程序启动的时候执行的代码部分,并且它在整个过程中只执行一次,我们可以在开始块中初始化一些变量。

    主体块(BODY)

    pattern {awk-commands}
    
    • 1

    默认情况下,对于输入的每一行,awk 都会执行命令,我们可以通过 pattern 将其限定在指定的模式中,这部分也是可选的,不存在也是可以的,不过不存在主体的脚本用处不大。

    结束块(END)

    END {awk-commands}
    
    • 1

    结束块部分是可选的,可以没有结束块部分,是在程序结束时执行的代码。 如果存在必须以 END 开头

    /etc/passwd文件

    起初 /etc/passwd 文件包含了用户名和密码,但是由于该文件允许所有用户读取,易导致用户密码泄露,因此 Linux 系统将用户的密码信息从 /etc/passwd 文件中分离出来,并单独放到了/etc/shadow 文件中,此文件只有 root 用户拥有读权限,其他用户没有任何权限,这样就一定程度上保证了用户密码的安全性。

    /etc/passwd 配置文件的内容用冒号 : 隔开分为7段,分别为:

    1. 用户名:账户名字
    2. x:早期这个部分放的是用户登入密码,现在的密码是放入/etc/shadow中的
    3. UID:用户ID,0表示系统管理员,1~999保留给系统使用的ID,1000以上给一般使用者
    4. GID:组ID,0表示系统管理员,1~999保留给系统使用的ID,1000以上给一般使用者
    5. 使用者的信息说明
    6. 用户家目录:用户登入时所在的目录
    7. 默认shell:用户在登入的时候,默认使用的shell类型,如果不能使用shell,则会显示/sbin/nologin

    /etc/shadow 配置文件的内容用冒号 : 隔开分为9段,分别为:

    1. 用户名
    2. 经过加密的密码( * 表示用户被锁定,!表示无加密)
    3. 最近更改过密码的日期:Linux中的日期是经过1970年1月1号开始累计的日期
    4. 密码不能修改的天数,0表示随时可以修改
    5. 密码需要重新被修改的天数,通过修改该值可以强制修改密码
    6. 密码需要变更的告警天数,7表示系统会向用户发出警告的天数
    7. 密码到期后帐号可以使用的时间
    8. 帐号失效日期,通过1970年1月1号开始累加的日期,到了时间后无论密码是否过期,该账号就不能再使用了
    9. 保留的

    如果忘记自己的账户密码,该怎么处理呢?

    • 对于普通账户的密码遗失,可以通过 root 账户使用 passwd 命令重新设置密码解决,passwd username

    • 如果 root 账号的密码遗失,则需要重新启动进入单用户模式,系统会提供 root 权限的 bash 接口,此时可以用 passwd 命令修改账户密码。或者通过挂载根目录,修改 /etc/shadow 文件将 root 密码清空,无密码即登陆后再使用 passwd 命令配置 root 密码。

    awk 常用处理

    字段分割及相关变量

    • $1,$2, 3... 3... 3...n:awk中用该顺序形式表示files中每行以间隔符号分割的各列的不同字段
    • $0:表示文本本身
    • NF:表示当前记录的字段数(列数)
    • $NF:最后一列
    • $(NF-1):倒数第二列
    • FNR/NR:行号
    • FILENAME:文件名
    • “\t”:制表符
    • RS:换行符
    • “”: 打印字符串
    • FS:定义间隔符
    • ~:匹配,与==相比不是精确比较
    • !~:不匹配,不精确比较
    • ==:等于,必须全部相等,精确比较
    • /[0-9][0-9]+/:两个或两个以上数字
    • -F’[:#]':定义两个分隔符

    常用处理

    添加表头

    [root@VM-0-3-centos ~]# awk -F: 'BEGIN{print"用户名\t密码\tUID\tGID\t信息\t家目录\tshell"}{printf $1"\t"$2"\t"$3"\t"$4"\t"$5"\t"$6"\t"$7"\n"}' /etc/passwd
    用户名 密码  UID GID 信息  家目录 shell
    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
    sync    x   5   0   sync    /sbin   /bin/sync
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    添加行号

    [root@VM-0-3-centos ~]# awk -F: '{printf NR"\t"$0"\n"}' /etc/passwd
    1   root:x:0:0:root:/root:/bin/bash
    2   bin:x:1:1:bin:/bin:/sbin/nologin
    3   daemon:x:2:2:daemon:/sbin:/sbin/nologin
    4   adm:x:3:4:adm:/var/adm:/sbin/nologin
    5   lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    6   sync:x:5:0:sync:/sbin:/bin/sync
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    打印第三行第1列和第7列

    [root@VM-0-3-centos ~]# awk -F: 'NR==3{print $1"\t"$7}' /etc/passwd
    daemon  /sbin/nologin
    
    • 1
    • 2

    打印文件总行数

    [root@VM-0-3-centos ~]# awk -F: 'END{print FILENAME"\t"NR}' /etc/passwd
    /etc/passwd 28
    
    • 1
    • 2

    查询不能登录的用户数

    [root@VM-0-3-centos ~]# awk -F: 'BEGIN{x=0} {if($7=="/sbin/nologin") x++} END{print FILENAME"\t"x}' /etc/passwd
    /etc/passwd 21
    
    • 1
    • 2
    [root@VM-0-3-centos ~]# awk '/nologin/' /etc/passwd | wc -l
    21
    
    • 1
    • 2

    查询可以登录的用户

    [root@VM-0-3-centos ~]# awk -F: '$NF !~ /nologin$/{print $1}'  /etc/passwd
    root
    sync
    
    • 1
    • 2
    • 3

    打印UID小于300的用户

    [root@VM-0-3-centos ~]#  awk -F: '{ if($3<300) print $1"\t"$3 }' /etc/passwd
    root    0
    bin     1
    daemon  2
    adm     3
    lp      4
    sync    5
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    打印UID在2和6之间的用户

    [root@VM-0-3-centos ~]#  awk -F: '($3>2&&$3<6){print $1"\t"$3 }' /etc/passwd
    adm     3
    lp      4
    sync    5
    
    • 1
    • 2
    • 3
    • 4

    进行算术运算

    [root@VM-0-3-centos ~]#  awk -F: '($3*2 < 6){print $1"\t"$3 }' /etc/passwd
    root    0
    bin     1
    daemon  2
    
    • 1
    • 2
    • 3
    • 4

    利用条件判断统计各类用户数

    [root@VM-0-3-centos ~]# awk -F: '{if($3==0){i++} else if($3>999){k++} else{j++}} END{print "管理员个数: "i; print "普通用个数: "k; print "系统用户数: "j}' /etc/passwd
    管理员个数: 1
    普通用个数: 1
    系统用户数: 26
    
    • 1
    • 2
    • 3
    • 4

    每行数据打印3遍

    [root@VM-0-3-centos ~]# awk -F: '{for(i=1;i<=3;i++) print NR"\t"i"\t"$0}' /etc/passwd
    1   1   root:x:0:0:root:/root:/bin/bash
    1   2   root:x:0:0:root:/root:/bin/bash
    1   3   root:x:0:0:root:/root:/bin/bash
    2   1   bin:x:1:1:bin:/bin:/sbin/nologin
    2   2   bin:x:1:1:bin:/bin:/sbin/nologin
    2   3   bin:x:1:1:bin:/bin:/sbin/nologin
    3   1   daemon:x:2:2:daemon:/sbin:/sbin/nologin
    3   2   daemon:x:2:2:daemon:/sbin:/sbin/nologin
    3   3   daemon:x:2:2:daemon:/sbin:/sbin/nologin
    4   1   adm:x:3:4:adm:/var/adm:/sbin/nologin
    4   2   adm:x:3:4:adm:/var/adm:/sbin/nologin
    4   3   adm:x:3:4:adm:/var/adm:/sbin/nologin
    5   1   lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    5   2   lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    5   3   lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    统计/etc/passwd中各种类型shell的数量

    [root@VM-0-3-centos ~]# awk -F: '{shells[$NF]++}END{ for(i in shells){print i,shells[i]}}' /etc/passwd
    /bin/sync 1
    /bin/bash 3
    /sbin/nologin 21
    /sbin/halt 1
    /bin/false 1
    /sbin/shutdown 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    网站访问状态统计

    [root@VM-0-3-centos ~]# netstat -ant | grep :80 | awk '{access_stat[$NF]++}END{for(i in access_stat){print i, access_stat[i]}}'
    LISTEN 3
    CLOSE_WAIT 1
    ESTABLISHED 1
    
    • 1
    • 2
    • 3
    • 4

    生成清空arp命令的文本

    [root@VM-0-3-centos ~]# arp | awk '!/Address/{print "arp -d " $1}'
    arp -d 169.254.0.2
    arp -d 169.254.0.3
    arp -d 169.254.0.79
    arp -d 172.18.0.3
    arp -d 169.254.128.8
    arp -d 169.254.128.9
    arp -d 10.10.0.17
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    直接在末尾加管道 bash 就可以执行了,arp | awk '!/Address/{print "arp -d " $1}'| bash 这是一种通用的生成处理命令的方式,先生成命令文本,然后作为bash输入,执行即可。

    总结

    • awk 处理流程分为3个阶段,BEGIN块、BODY块、END块,其中BEGIN块和END块都执行一次,BODY块对每一行输入执行一次
    • awk 的3个处理块都是可选的,对于待处理的文件,一般至少会包含BODY块
    • awk 中BODY块的 pattern 用于行过滤,/pattern/ 表示匹配,/!pattern/ 表示不匹配
    • awk 中BODY块的中也可对指定字段判断是否包含,'$1 ~ /root/' 表示第一列包含root,'$NF !~ /nologin$/' 表示最后一列不包含nologin
    • awk 还可用于待处理命令文本的预处理,先将过滤文本拼装成命令文本,然后利用管道直接通过bash执行

    ==>> 反爬链接,请勿点击,原地爆炸,概不负责!<<==

    最近有些急躁,虽知欲速则不达,但压力之下确实难以平静。之所以这么拼,并不是为了卷谁,也不是为了表现给别人看,只是想有所提升超越昨天的自己,目的也非常俗套,通过提升自身来给自己的小家一个更好的生活。“一室之不治,何以天下家国为?”如果每个人都能把自己的小日子过好,则天下太平!

  • 相关阅读:
    Python_偏函数
    【React 源码】(十五)React Context 原理
    PTA: 字符串的模式匹配
    ArcGIS Pro实践技术应用、制图、空间分析、影像分析、三维建模、空间统计分析与建模、python融合
    技术人员如何培养业务的敏感度?掌握原动力和方法
    纳米软件介绍什么是LABVIEW?
    vue3学习源码笔记(小白入门系列)------provide和 inject 跨层级数据传递原理
    Spring Security基本框架之认证和授权
    vue3项目集成TypeScript
    【C++进阶(五)】STL大法--list模拟实现以及list和vector的对比
  • 原文地址:https://blog.csdn.net/shihengzhen101/article/details/127606837