一、awk

1. awk的工作原理

逐行读取文本,默认以空格或tab键为分隔符进行分割,将分割所得的各个字段保存到内建变量中,并按模式或者条件执行编辑命令。
sed命令常用语一整行的处理,而awk比较倾向于将一行分成多个“字段”然后再进行处理。awk信息的读入也是逐行读取的,执行结果可以通过print的功能将字段数据打印显示。在使用awk命令的过程中,可以使用逻辑操作符“&&”表示“与”、“||”表示“或”、“!”表示“非”;还可以进行简单的数学运算,如+、-、*、/、%、^分别表示加、减、乘、除、取余和乘方。

2. 命令格式

awk 选项 '模式或条件 {操作}' 文件1 文件2 ……
awk -f 脚本文件 文件1 文件2 ……

3. awk常见的内建变量(可直接用)

内建变量 说明
FS 列分隔符。指定每行文本的字段分隔符,默认为空格或制表位。与“-F”作用相同
NF 当前处理的行的字段个数
NR 当前处理的行的行号(序数)
$0 当前处理的行的整行内容
$n 当前处理行的第n个字段(第n列)
FILENAME 被处理的文件名
RS 行分隔符。awk从文件上读取资料时,将根据RS的定义把资料切割成许多条记录,而awk一次仅读入一条记录,以进行处理。预设值是“\n”

二、操作实例

1. 按行输出文本

awk '{print}' 文件名

输出所有内容

[root@localhost ~]# cat test.txt 
11
22
33
44
[root@localhost ~]# awk '{print}' test.txt 
11
22
33
44

awk '{print $0}' 文件名
输出所有内容

[root@localhost ~]# awk '{print $0}' test.txt 
11
22
33
44

awk 'NR==n,NR==m {print}' 文件名
输出第n行至第m行的内容

[root@localhost ~]# awk 'NR==1,NR==3 {print $0}' test.txt 
11
22
33

awk '(NR>=n) && (NR<=m) {print}' 文件名
输出第n行至第m行的内容

[root@localhost ~]# awk '(NR>=1) && (NR<=3) {print}' test.txt 
11
22
33

awk 'NR==n || NR==m {print}' 文件名
输出第n行和第m行的内容

[root@localhost ~]# awk 'NR==1 || NR==3 {print}' test.txt 
11
33

awk '(NR%2)==1 {print}' 文件名
输出所有奇数行的内容

[root@localhost ~]# awk '(NR%2)==1 {print}' test.txt 
11
33

awk '(NR%2)==0 {print}' 文件名
输出所有偶数行的内容

[root@localhost ~]# awk '(NR%2)==1 {print}' test.txt 
22
44

awk '/^a/ {print}' 文件名
输出以字符串a开头的行

[root@localhost ~]# awk '/^3/ {print}' test.txt 
33

awk '/a$/ {print}' 文件名
输出以字符串a结尾的行

[root@localhost ~]# awk '/4$/ {print}' test.txt 
44

awk 'BEGIN {x=0}; /^a/ {x++}; END {print x}' 文件名
输出文件中以字符串a开头行的数量

BEGIN模式表示,在处理指定的文本之前,需要先执行BEGIN模式中指定的动作;awk再处理指定的文本,之后再执行END模式中指定的动作,END{}语句块中,往往会放入打印结果等语句。

[root@localhost ~]# awk 'BEGIN{X=0}; /^root/ {x++}; END{print x}' /etc/passwd
1
[root@localhost ~]# awk 'BEGIN{X=0}; /nologin$/ {x++}; END{print x}' /etc/passwd
39

2. 按字段输出文本

awk -F ":" '{print $n}' 文件名
以:号为分隔符,输出每行的第n个字段

[root@localhost ~]# awk -F ":" '{print $1}' /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
games
ftp
nobody
systemd-network
dbus
polkitd
abrt
libstoragemgmt
rpc
colord
saslauth
setroubleshoot
rtkit
pulse
qemu
ntp
radvd
chrony
tss
usbmuxd
geoclue
sssd
gdm
rpcuser
nfsnobody
gnome-initial-setup
avahi
postfix
sshd
tcpdump
123456
named
dhcpd
apache

awk -F ":" '{print $n,$m}' 文件名
以:号为分隔符,输出每行的第n个和第m个字段

[root@localhost ~]# awk -F ":" '{print $1,$3}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
operator 11
games 12
ftp 14
nobody 99
systemd-network 192
dbus 81
polkitd 999
abrt 173
libstoragemgmt 998
rpc 32
colord 997
saslauth 996
setroubleshoot 995
rtkit 172
pulse 171
qemu 107
ntp 38
radvd 75
chrony 994
tss 59
usbmuxd 113
geoclue 993
sssd 992
gdm 42
rpcuser 29
nfsnobody 65534
gnome-initial-setup 991
avahi 70
postfix 89
sshd 74
tcpdump 72
123456 1000
named 25
dhcpd 177
apache 48

awk -F ":" '$n<m {print $n}' 文件名
以:号为分隔符,当第n个字段小于m时,输出第n个字段

[root@localhost ~]# awk -F ":" '$3<5 {print $1,$3}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4

awk -F ":" '!($n<m) {print}' 文件名
以:号为分隔符,当第n个字段不小于m时,输出整行内容

[root@localhost ~]# awk -F ":" '!($3<200) {print}' /etc/passwd
polkitd:x:999:997:User for polkitd:/:/sbin/nologin
libstoragemgmt:x:998:995:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
colord:x:997:994:User for colord:/var/lib/colord:/sbin/nologin
saslauth:x:996:76:Saslauthd user:/run/saslauthd:/sbin/nologin
setroubleshoot:x:995:993::/var/lib/setroubleshoot:/sbin/nologin
chrony:x:994:990::/var/lib/chrony:/sbin/nologin
geoclue:x:993:988:User for geoclue:/var/lib/geoclue:/sbin/nologin
sssd:x:992:987:User for sssd:/:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
gnome-initial-setup:x:991:986::/run/gnome-initial-setup/:/sbin/nologin
123456:x:1000:1000:123456:/home/123456:/bin/bash

awk 'BEGIN {FS=":"}; {if ($n>=m) {print}}' 文件名
以:号为分隔符,当第n列大于等于m时,输出整行内容

[root@localhost ~]# awk 'BEGIN {FS=":"}; {if ($3>=1000) {print}}' /etc/passwd
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
123456:x:1000:1000:123456:/home/123456:/bin/bash

awk -F ":" '{max=($n>=$m) ? $n : $m; {print max}}' 文件名
三元运算符。以:号为分隔符,如果第n个字段的值大于等于第m个字段的值,则把第n个字段的值赋给max,否则把第m个字段的值赋给max

[root@localhost ~]# awk -F ":" '{max=($3>=$4) ? $3 : $4; {print max}}' /etc/passwd
0
1
2
4
7
5
6
7
12
11
100
50
99
192
81
999
173
998
32
997
996
995
172
171
107
38
75
994
59
113
993
992
42
29
65534
991
70
89
74
72
1000
25
177
48

awk -F ":" '{print NR,$0}' 文件名
以:号为分隔符,处理每行内容和行号,没处理完一条记录,NR值加1

[root@localhost ~]# awk -F ":" '{print NR,$0}' /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
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 operator:x:11:0:operator:/root:/sbin/nologin
11 games:x:12:100:games:/usr/games:/sbin/nologin
12 ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
13 nobody:x:99:99:Nobody:/:/sbin/nologin
14 systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
15 dbus:x:81:81:System message bus:/:/sbin/nologin
16 polkitd:x:999:997:User for polkitd:/:/sbin/nologin
17 abrt:x:173:173::/etc/abrt:/sbin/nologin
18 libstoragemgmt:x:998:995:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
19 rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
20 colord:x:997:994:User for colord:/var/lib/colord:/sbin/nologin
21 saslauth:x:996:76:Saslauthd user:/run/saslauthd:/sbin/nologin
22 setroubleshoot:x:995:993::/var/lib/setroubleshoot:/sbin/nologin
23 rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin
24 pulse:x:171:171:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
25 qemu:x:107:107:qemu user:/:/sbin/nologin
26 ntp:x:38:38::/etc/ntp:/sbin/nologin
27 radvd:x:75:75