一、awk工具的使用 awk和sed一样是流式编辑器,它也是针对文档中的行来操作的。它比sed更强大,相对sed它支持分段,

1、截取文件中的某个段

awk -F ':' '{print $1}' test.txt 打印第一段; awk -F ':' '{print $0}' test.txt 打印所有段; 不指定分隔符:(无论指定哪一行都会打印抽有段) awk '{print $1}' test.txt awk '{print $0}' test.txt -F 指定分隔符,如果不加-F指定,则以空格或者tab为分隔符 $1 第1字段,$2第2字段,$0表示整行

print 打印,print的动作要用 { } 括起来,它还可以打印自定义的内容。但自定义的内容要用双引号引起来。如果你在{}外加双引号,无语指定哪一段,它都会把内容全部打印出来。例:

head -2 /etc/passwd |awk -F ':' '{print $1"#"$2"#"$3"#"$4}'
[root@riven ~]# head -2 /etc/passwd |awk -F ':' '{print $1"#"$2"#"$3"#"$4}'
root#x#0#0
bin#x#1#1
[root@riven ~]# 

2、匹配字符或字符串(跟sed用法差不多)

awk '/oo/' test.txt 匹配有oo的行 awk -F ':' '$1 ~ /oo/' test.txt 第一段包括oo的行。 awk -F ':' '$1~ /o+/' test.txt 匹配所有包括o的行

[root@riven ~]# awk -F ':' '$1~ /oo/' test.txt
root:x:0:0:root:/root:/bin/bash
[root@riven ~]# awk -F ':' '$1~ /o+/' test.txt
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
operator:x:11:0:operator:/root:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
polkitd:x:999:997:User for polkitd:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
[root@riven ~]# awk -F ':' '$1~ /oo+/' test.txt
root:x:0:0:root:/root:/bin/bash
[root@riven ~]# 

同时支持多个表达式同时写,多次匹配,匹配完root,再匹配test,它还可以只打印所匹配的段 awk -F ':' '/test/ {print $1,$3} /root/ {print $1,$3} /user/ {print $1,$3,$4}' test.txt 检查这些段是不是有包括root 跟test,user grep -nE 'test|root|user' test.txt awk -F ':' '/test|root|user/ {print $0}' test.txt

[root@riven ~]# awk -F ':' '/test/ {print $1,$3} /root/ {print $1,$3} /user/ {print $1,$3,$4}' test.txt 
root 0
operator 11
test 1003
user2 1004 1004
saslauth 997 76
[root@riven ~]# grep -nE 'test|root|test' test.txt
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin
24:test:x:1003:1001::/home/test:/bin/bash
[root@riven ~]# grep -nE 'test|root|user' test.txt
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin
24:test:x:1003:1001::/home/test:/bin/bash
25:user2:x:1004:1004::/home/user2:/bin/bash
28:saslauth:x:997:76:Saslauthd user:/run/saslauthd:/sbin/nologin
[root@riven ~]# awk -F ':' '/test|root|user/ {print $0}' test.txt
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
test:x:1003:1001::/home/test:/bin/bash
user2:x:1004:1004::/home/user2:/bin/bash
saslauth:x:997:76:Saslauthd user:/run/saslauthd:/sbin/nologin
[root@riven ~]# 

3、条件操作符

awk中是可以用逻辑符号判断的,比如 ‘==’ 就是等于,也可以理解为 ‘精确匹配’ 另外也有 >, ‘>=, ‘<, ‘<=, ‘!= 等等, awk -F ':' '$3==0' test.txt awk -F ':' '$3==0' {print $3}' test.txt

[root@riven ~]# awk -F ':' '$3==0' test.txt
root:x:0:0:root:/root:/bin/bash
[root@riven ~]# awk -F ':' '$3==0 {print $3}' test.txt 
0
[root@riven ~]# 

在和数字比较时,若把比较的数字用双引号引起来后,那么awk会认为是字符,不加双引号则认为是数字。 例: awk -F ':' '$3 >=500 {print $3}' test.txt 打印UID大于或等于500的行 awk -F ':' '$3 >="500" {print $3}' test.txt

[root@riven ~]# awk -F ':' '$3 >=500 {print $3}' test.txt 
999
998
1000
1003
1004
1005
997
[root@riven ~]# awk -F ':' '$3 >="500" {print $3}' test.txt
6
7
8
99
81
999
89
998
74
72
997
[root@riven ~]# 
[root@riven ~]# awk -F ':' '$3 >=500' test.txt 
polkitd:x:999:997:User for polkitd:/:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
riven:x:1000:1000::/home/riven:/bin/bash
test:x:1003:1001::/home/test:/bin/bash
user2:x:1004:1004::/home/user2:/bin/bash
httpd:x:1005:1012::/home/httpd:/bin/nologin
saslauth:x:997:76:Saslauthd user:/run/saslauthd:/sbin/nologin
[root@riven ~]# 

!= 不等于,不匹配,字符串要加上双引号“”

例:awk -F ':' '$7!="/sbin/nologin"' test.txt 不匹配/sbin/nologin ,

[root@riven ~]# awk -F ':' '$7!="/sbin/nologin"' test.txt 
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
riven:x:1000:1000::/home/riven:/bin/bash
test:x:1003:1001::/home/test:/bin/bash
user2:x:1004:1004::/home/user2:/bin/bash
httpd:x:1005:1012::/home/httpd:/bin/nologin
[root@riven ~]# 

除了针对某一个段的字符进行逻辑比较外,还可以两个段之间进行逻辑比较。 例:awk -F ':' '$3<$4' test.txt 第三个字符小于第四个字符的项。

[root@riven ~]# awk -F ':' '$3>$4' test.txt 
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
operator:x:11:0:operator:/root:/sbin/nologin
polkitd:x:999:997:User for polkitd:/:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
test:x:1003:1001::/home/test:/bin/bash
saslauth:x:997:76:Saslauthd user:/run/saslauthd:/sbin/nologin

&& 和 || 表示 “并且” 和 “或者” 的意思。 awk -F ':' '$3>"5" && $3<"7"' test.txt 5跟7为字符串,要用双引号引起来 awk -F ':' '$3>1000 || $7="/sbin/nologin"' test.txt

 [root@riven ~]#  awk -F ':' '$3>"5" && $3<"7"' test.txt
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
[root@riven ~]# awk -F ':' '$3>1000 || $7="/sbin/nologin"' test.txt
root x 0 0 root /root /sbin/nologin
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 /sbin/nologin
shutdown x 6 0 shutdown /sbin /sbin/nologin
halt x 7 0 halt /sbin /sbin/nologin
mail x 8 12 mail /var/spool/mail /sbin/nologin
operator x 11 0 operator /root /sbin/nologin
games x 12 100 games /usr/games /sbin/nologin
ftp x 14 50 FTP User /var/ftp /sbin/nologin
nobody x 99 99 Nobody / /sbin/nologin
systemd-network x 192 192 systemd Network Management / /sbin/nologin
dbus x 81 81 System message bus / /sbin/nologin
polkitd x 999 997 User for polkitd / /sbin/nologin
postfix x 89 89  /var/spool/postfix /sbin/nologin
chrony x 998 996  /var/lib/chrony /sbin/nologin
sshd x 74 74 Privilege-separated SSH /var/empty/sshd /sbin/nologin
ntp x 38 38  /etc/ntp /sbin/nologin
tcpdump x 72 72  / /sbin/nologin
nscd x 28 28 NSCD Daemon / /sbin/nologin
riven x 1000 1000  /home/riven /sbin/nologin
test:x:1003:1001::/home/test:/bin/bash
user2:x:1004:1004::/home/user2:/bin/bash
httpd:x:1005:1012::/home/httpd:/bin/nologin
apache x 48 48 Apache /usr/share/httpd /sbin/nologin
saslauth x 997 76 Saslauthd user /run/saslauthd /sbin/nologin
[root@riven ~]#

4、awk的内置变量

awk常用的变量有: OFS 如果有多段,用来指定print 用到的分隔符, awk -F ':' '{OFS="#" } $3>1000 || $7="/sbin/nologin" {print $1,$3,$5,$7}' test.txt

[root@riven ~]# awk -F ':' '{OFS="#" } $3>1000 || $7="/sbin/nologin" {print $1,$3,$5,$7}' test.txt
root#0#root#/sbin/nologin
bin#1#bin#/sbin/nologin
daemon#2#daemon#/sbin/nologin
adm#3#adm#/sbin/nologin
lp#4#lp#/sbin/nologin
sync#5#sync#/sbin/nologin
shutdown#6#shutdown#/sbin/nologin
halt#7#halt#/sbin/nologin
mail#8#mail#/sbin/nologin
operator#11#operator#/sbin/nologin
games#12#games#/sbin/nologin
ftp#14#FTP User#/sbin/nologin
nobody#99#Nobody#/sbin/nologin
systemd-network#192#systemd Network Management#/sbin/nologin
dbus#81#System message bus#/sbin/nologin
polkitd#999#User for polkitd#/sbin/nologin
postfix#89##/sbin/nologin
chrony#998##/sbin/nologin
sshd#74#Privilege-separated SSH#/sbin/nologin
ntp#38##/sbin/nologin
tcpdump#72##/sbin/nologin
nscd#28#NSCD Daemon#/sbin/nologin
riven#1000##/sbin/nologin
test#1003##/bin/bash
user2#1004##/bin/bash
httpd#1005##/bin/nologin
apache#48#Apache#/sbin/nologin
saslauth#997#Saslauthd user#/sbin/nologin
[root@riven ~]# 

awk -F ':' '{OFS="#"} {if ($3>1000) {print $1,$2,$3,$4}}' test.txt

[root@riven ~]# awk -F ':' '{OFS="#"} {if ($3>1000) {print $1,$2,$3,$4}}' test.txt
test#x#1003#1001
user2#x#1004#1004
httpd#x#1005#1012
[root@riven ~]# 

NR :行数 awk -F ':' '{print NR":"$0}' test.txt 打印所有的行号

[root@riven ~]# awk -F ':' '{print NR":"$0}' test.txt 
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:postfix:x:89:89::/var/spool/postfix:/sbin/nologin
18:chrony:x:998:996::/var/lib/chrony:/sbin/nologin
19:sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
20:ntp:x:38:38::/etc/ntp:/sbin/nologin
21:tcpdump:x:72:72::/:/sbin/nologin
22:nscd:x:28:28:NSCD Daemon:/:/sbin/nologin
23:riven:x:1000:1000::/home/riven:/bin/bash
24:test:x:1003:1001::/home/test:/bin/bash
25:user2:x:1004:1004::/home/user2:/bin/bash
26:httpd:x:1005:1012::/home/httpd:/bin/nologin
27:apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
28:saslauth:x:997:76:Saslauthd user:/run/saslauthd:/sbin/nologin
[root@riven ~]# 

打印前10行: awk -F ':' 'NR<=10' test.txt 打印前面10行且包括root和sync的 awk -F ':' 'NR<=10 && /root|sync/' test.txt NF :用分隔符分隔后一共有多少段` awk -F ':' '{print NF":"$0}' test.txt

[root@riven ~]# awk -F ':' '{print NF":"$0}' test.txt 
7:root:x:0:0:root:/root:/bin/bash
7:bin:x:1:1:bin:/bin:/sbin/nologin
7:daemon:x:2:2:daemon:/sbin:/sbin/nologin
7:adm:x:3:4:adm:/var/adm:/sbin/nologin
7:lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
7:sync:x:5:0:sync:/sbin:/bin/sync
7:shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
7:halt:x:7:0:halt:/sbin:/sbin/halt
7:mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
7:operator:x:11:0:operator:/root:/sbin/nologin
7:games:x:12:100:games:/usr/games:/sbin/nologin
7:ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
7:nobody:x:99:99:Nobody:/:/sbin/nologin
7:systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
7:dbus:x:81:81:System message bus:/:/sbin/nologin
7:polkitd:x:999:997:User for polkitd:/:/sbin/nologin
7:postfix:x:89:89::/var/spool/postfix:/sbin/nologin
7:chrony:x:998:996::/var/lib/chrony:/sbin/nologin
7:sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
7:ntp:x:38:38::/etc/ntp:/sbin/nologin
7:tcpdump:x:72:72::/:/sbin/nologin
7:nscd:x:28:28:NSCD Daemon:/:/sbin/nologin
7:riven:x:1000:1000::/home/riven:/bin/bash
7:test:x:1003:1001::/home/test:/bin/bash
7:user2:x:1004:1004::/home/user2:/bin/bash
7:httpd:x:1005:1012::/home/httpd:/bin/nologin
7:apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
7:saslauth:x:997:76:Saslauthd user:/run/saslauthd:/sbin/nologin
[root@riven ~]# 

NF 是多少段,而$NF是最后一段的值, 而NR则是行号。$NR对应的是:行号是几显示的就是第几个段的字符。

awk -F ':' '{print $NR":"$NF}' test.txt

5、awk中的数学运算

awk可以把段值更改: 例: head -n 3 /etc/passwd |awk -F ':' '$1="root"' 前三行的第一段赋值成root 但进行赋值之后没有了: 那我们就需要定义OFS head -3 /etc/passwd |awk -F ':' '{OFS=":"} $1="root"'


[root@riven ~]# head -3 /etc/passwd |awk -F ':' '{OFS=":"} $1="root"'
root:x:0:0:root:/root:/bin/bash
root:x:1:1:bin:/bin:/sbin/nologin
root:x:2:2:daemon:/sbin:/sbin/nologin
[root@riven ~]# head -3 /etc/passwd |awk -F ':' ' $1="root"' 
root x 0 0 root /root /bin/bash
root x 1 1 bin /bin /sbin/nologin
root x 2 2 daemon /sbin /sbin/nologin
[root@riven ~]# 

对各个段的值进行数学运算:

计算某个段的总和:tot求和。 awk -F ':' '{(tot=tot+$3)};END {print tot}' test.txt 给文件所有行的第三段求和

[root@riven ~]# awk -F ':' '{(tot=tot+$3)};END {print tot}' test.txt
7800
[root@riven ~]#

在awk中使用if判断、for循环:

[root@riven ~]# awk -F ':' '{if ($1=="root") print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@riven ~]#