awk 是 linux 环境下的一个强大的编程工具,用于对文本和数据进行处理。数据可以来自标准输入、一个或多个文件,或其它命令的输出。同时它支持用户自定义函数和动态正则表达式等先进功能,可以被作为一种编程语言,可以很方便的在命令行中使用,但更多是在脚本来使用,为了熟悉这个命令,我们可以用它来尝试处理 /etc/passwd 文件学习一下常见用法。
awk 这个名字来源于它的三个作者姓氏的第一个字母,分别是Alfred Aho、Brian Kernighan、Peter Weinberger,常用的版本是 gawk, 它是awk的GNU版本,提供了Bell实验室和GNU的一些扩展。
awk 工作流程可分为三个部分:
命令结构:
awk 'BEGIN{ commands } pattern{ commands } END{ commands }'
BEGIN {awk-commands}
开始块部分是可选的,可以没有开始块部分,如果存在必须以 BEGIN 开头
开始块就是在程序启动的时候执行的代码部分,并且它在整个过程中只执行一次,我们可以在开始块中初始化一些变量。
pattern {awk-commands}
默认情况下,对于输入的每一行,awk 都会执行命令,我们可以通过 pattern 将其限定在指定的模式中,这部分也是可选的,不存在也是可以的,不过不存在主体的脚本用处不大。
END {awk-commands}
结束块部分是可选的,可以没有结束块部分,是在程序结束时执行的代码。 如果存在必须以 END 开头
起初 /etc/passwd 文件包含了用户名和密码,但是由于该文件允许所有用户读取,易导致用户密码泄露,因此 Linux 系统将用户的密码信息从 /etc/passwd 文件中分离出来,并单独放到了/etc/shadow 文件中,此文件只有 root 用户拥有读权限,其他用户没有任何权限,这样就一定程度上保证了用户密码的安全性。
/etc/passwd 配置文件的内容用冒号 : 隔开分为7段,分别为:
/etc/shadow 配置文件的内容用冒号 : 隔开分为9段,分别为:
如果忘记自己的账户密码,该怎么处理呢?
对于普通账户的密码遗失,可以通过 root 账户使用 passwd 命令重新设置密码解决,passwd username。
如果 root 账号的密码遗失,则需要重新启动进入单用户模式,系统会提供 root 权限的 bash 接口,此时可以用 passwd 命令修改账户密码。或者通过挂载根目录,修改 /etc/shadow 文件将 root 密码清空,无密码即登陆后再使用 passwd 命令配置 root 密码。
[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
[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
[root@VM-0-3-centos ~]# awk -F: 'NR==3{print $1"\t"$7}' /etc/passwd
daemon /sbin/nologin
[root@VM-0-3-centos ~]# awk -F: 'END{print FILENAME"\t"NR}' /etc/passwd
/etc/passwd 28
[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
[root@VM-0-3-centos ~]# awk '/nologin/' /etc/passwd | wc -l
21
[root@VM-0-3-centos ~]# awk -F: '$NF !~ /nologin$/{print $1}' /etc/passwd
root
sync
[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
[root@VM-0-3-centos ~]# awk -F: '($3>2&&$3<6){print $1"\t"$3 }' /etc/passwd
adm 3
lp 4
sync 5
[root@VM-0-3-centos ~]# awk -F: '($3*2 < 6){print $1"\t"$3 }' /etc/passwd
root 0
bin 1
daemon 2
[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
[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
[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
[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
[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
直接在末尾加管道 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$/' 表示最后一列不包含nologinawk 还可用于待处理命令文本的预处理,先将过滤文本拼装成命令文本,然后利用管道直接通过bash执行最近有些急躁,虽知欲速则不达,但压力之下确实难以平静。之所以这么拼,并不是为了卷谁,也不是为了表现给别人看,只是想有所提升超越昨天的自己,目的也非常俗套,通过提升自身来给自己的小家一个更好的生活。“一室之不治,何以天下家国为?”如果每个人都能把自己的小日子过好,则天下太平!