一、awk简介
- 在 Linux/UNIX 系统中,awk 是一个功能强大的编辑工具,逐行读取输入文本,并根据指定的匹配模式进行查找,对符合条件的内容进行格式化输出或者过滤处理
- 可以在无交互的情况下实现相当复杂的文本操作,被广泛应用于 Shell 脚本,完成各种自动化配置任务
二、awk常见用法
- 通常情况下 awk 所使用的命令格式为
[root@localhost ~]# awk 选项 '模式或条件 {编辑指令}' 文件 1 文件 2 „ '过滤并输出文件符条件的内容'
[root@localhost ~]# awk -f 脚本文件 文件 1 文件 2 „ '从脚本中调用编辑指令,过滤并输出内容'
其中,单引号加上大括号“{}”用于设置对数据进行的处理动作
awk 可以直接处理目标文件,也可以通过“-f”读取脚本对目标文件进行处理
-
sed 命令常用于一整行的处理,而 awk 比较倾向于将一行分成多个“字段”然后再进行处理,且默认情况下字段的分隔符为空格或者 tab 键,awk 执行结果可以通过 print 的功能将字段数据打印显示
-
在使用 awk 命令的过程中,可以使用逻辑操作符“ && ”,表示“与”, “ || ”表示“或”,“!”表示“非”;还可以进行简单的数学运算,如+、-、*、/、%、^分别 表示加、减、乘、除、取余和乘方
[root@localhost ~]# awk -F ':' '{print $1,$3,$4}' /etc/passwd '查看/etc/passwd的用户名($1),用户ID($3),组ID等列($4)'
$1,$3,$4之间用逗号隔开,输出的内容会有空格间隔
若$1 $3 $4之间不用逗号隔开,则输出的内容不会有空格间隔,会连在一起
2.1、awk的内建变量
2.2、按行输出文本
[root@localhost ~]# awk '{print}' test.txt '输出所有内容,等同于cat test.txt'
...省略内容
[root@localhost ~]# awk '{print $0}' test.txt '输出所有内容,等同于cat test.txt'
...省略内容
[root@localhost ~]# awk 'NR==1,NR==3{print}' test.txt '输出第1~3行内容'
...省略内容
[root@localhost ~]# awk '(NR>=1)&&(NR<=3){print}' test.txt '输出第1~3行内容'
...省略内容
[root@localhost ~]# awk 'NR==1||NR==3{print}' test.txt '输出1行,第3行内容'
...省略内容
[root@localhost ~]# awk '(NR%2)==1{print}' test.txt '输出所有奇数行内容'
...省略内容
[root@localhost ~]# awk '(NR%2)==0{print}' test.txt '输出所有偶数行内容'
...省略内容
[root@localhost ~]# awk '/^root/{print}' /etc/passwd '输出以root开头的行'
...省略内容
[root@localhost ~]# awk '/nologin$/{print}' /etc/passwd '输出以 nologin 结尾的行'
...省略内容
[root@localhost ~]# awk 'BEGIN {x=0} ; /\/bin\/bash$/{x++};END {print x}' /etc/passwd '统计以/bin/bash 结尾的行数,等同于 grep -c "/bin/bash$" /etc/passwd '
...省略内容
[root@localhost ~]# awk 'BEGIN{RS=""};END{print NR}' /etc/squid/squid.conf '统计以空行分隔的文本段落数'
...省略内容
2.3、按字段输出文本
[root@localhost ~]# awk '{print $3}' test.txt '输出每行中(以空格或制表位分隔)的第 3 个字段'
...省略内容
[root@localhost ~]# awk '{print $1,$3}' test.txt '输出每行中的第 1、3 个字段'
...省略内容
[root@localhost ~]# awk -F: '$2=="!!"{print}' /etc/shadow '输出密码为空的用户的shadow 记录'
...省略内容
[root@localhost ~]# awk 'BEGIN {FS=":"}; $2=="!!"{print}' /etc/shadow '输出密码为空的用户的shadow 记录'
...省略内容
[root@localhost ~]# awk -F: '$7~"/bash"{print $1}' /etc/passwd '输出以冒号分隔且第 7 个字段中包含/bash 的行的第 1 个字段'
...省略内容
[root@localhost ~]# awk '($1~"nfs")&&(NF==8){print $1,$2}' /etc/services '输出包含 8 个字段且第 1 个字段中包含 nfs 的行的第 1、2 个字段'
...省略内容
[root@localhost ~]# awk -F: '($7!="/bin/bash")&&($7!="/sbin/nologin"){print}' /etc/passwd '输出第 7 个字段既不为/bin/bash 也不为/sbin/nologin 的所有行'
...省略内容
2.4、通过管道、双引号调用 Shell 命令
-
操作命令放在{}中
-
管道符号前面的命令输出的内容交给管道符号后面的命令处理
-
结合正则表达式,正则表达式同样要被/包围
-
调用的shell命令需要用""引起来
-
{}中多个命令之间也能过;分隔
[ root@localhost ~]# awk -F : '/bash$/{print | "wc -l"}' /etc/ passwd
7
#调用wc -I命令统计使用bash的用户个数,效果等同于grep -C
[ root@localhost ~]# grep -c '/bash$' /etc/passwd
[root@localhost ~]# awk 1 BEGIN {while ("w" lgetline)n++;{print n-2}}'
2
#调用w命令,并用来统计在线用户数
[ root@localhost ~]# awk 'BEGIN{ "hostname" | getline;print}'
localhost. localdomain
#调用hostname命令,并输出当前主机名
三、getline命令
1.当getline左右没有重定向符|或<时,getline读去当前文件的第一行并将数据保存到变量中,如果没有变量,则数据保存到$0中;由于awk在处理getline之前已经读入了一行,所以getline得到的返回结果是隔行的。
2.当getline左右有重定向符|或<时,getline作用于定向输入文件,由于该文件是刚打开,awk并没有读入一行数据,而getline读入了一行数据,那么getline返回的是该文件的第一行,而不是隔行。