awk介绍

awk工具的使用

awk也是流式编辑器,针对文档中的行来操作,一行一行地执行,awk兼具sed的所有功能,而且更加强大,awk工具其实是很复杂的(有专门的书来介绍它的应用,有兴趣的话自己可以去深入了解)。

awk比sed更丰富的功能是支持了分段,分段就是指比如passwd这个文件很有规律,它使用:号分隔成了七段,可以针对每个段做匹配,比如第一段匹配root的,把第一段有root的打印出来,第三段大于50或大于100的匹配出来.

截取文档中的某个段

打印第一段字符

[root@ataolinux-01 ~]# mkdir awk
[root@ataolinux-01 ~]# cp /etc/passwd awk/test.txt
[root@ataolinux-01 ~]# cd awk/
[root@ataolinux-01 awk]# ls
test.txt

[root@aminglinux-01 awk]# awk -F ':' '{print $1}' test.txt 
root
bin
daemon
adm
lp
sync
..省略

打印第一段到第三段,段之间加逗号

[root@aminglinux-01 awk]# awk -F ':' '{print $1,$2,$3}' test.txt 
root x 0
bin x 1
daemon x 2
..省略

打印所有的段

[root@aminglinux-01 awk]# awk -F ':' '{print $0}' test.txt    
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
...省略

#打印文件所有的内容,相当于cat
[root@ataolinux-01 awk]# awk '{print $0}' test.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin

说明:本例中,-F选项的作用就是指定分隔符,print为打印的动作,用来打印某个字段。$1为第1个字段,$2为第二个字段,以些类推,但$0比较特殊,它表示整行。

如果awk忽略了-F,没有指定分隔符,它默认将会以空格或空白字符去打印.测试如下:

[root@xietaolinux3 awk]# cat 1.txt 
1 1
aa bb
ss 22
[root@xietaolinux3 awk]# awk '{print $1}' 1.txt 
1
aa
ss

提醒:注意awk的格式,-F后面紧跟单引号,单引号里面为分隔符,print的动作要用{}括起来,否则会报错,print还可以打印自定义的内容,但是自定义的内容要用双引号括起来,如下所示:

#指定打印的段之间以什么为分隔,这里以#,要加双影号影起来
[root@aminglinux-01 awk]# awk -F ':' '{print $1"#"$2"#"$3"#"$4}' test.txt 
root#x#0#0
bin#x#1#1
daemon#x#2#2
adm#x#3#4
...省略
匹配字符或者字符串

打印包含oo的行

[root@aminglinux-01 awk]# awk '/00/' test.txt 
games:x:12:100:games:/usr/games:/sbin/nologin
aming:x:1000:1005::/home/aming:/bin/bash
user1:x:1001:1001::/home/user1:/bin/bash
aminglinux:x:1002:1002::/home/aminglinux:/bin/bash
user2:x:1003:1003::/home/user2:/bin/bash
user3:x:1004:1005::/home/user3:/bin/bash
user4:x:1006:1005::/home/aming111:/sbin/nologin
user5:x:1007:1007::/home/user5:/bin/bash
user6:x:1008:1010::/home/user6:/bin/bash

说明:这跟sed的用法类似,能实现grep的功能,但没有颜色显示,肯定没有grep用起来方便,不过awk还有比sed更强大的匹配,如下所示

打印匹配只要第一段带有oo的行

[root@aminglinux-01 awk]# awk -F ':' '$1 ~ /oo/' test.txt 
root:x:0:0:root:/root:/bin/bash

awk也支持正则表达式,匹配第一段带有o的行

[root@aminglinux-01 awk]# 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-bus-proxy:x:999:997:systemd Bus Proxy:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
polkitd:x:998:996:User for polkitd:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
chrony:x:997:995::/var/lib/chrony:/sbin/nologin
[root@aminglinux-01 awk]# awk -F ':' '$1 ~ /oo+/' test.txt 
root:x:0:0:root:/root:/bin/bash

[root@xietaolinux3 awk]# awk -F ':' '$1 ~ /oo+/' test.txt 
root:x:0:0:root:/root:/bin/bash

它可以让某个段匹配,这里的~就是匹配的意思,awk还可以多次匹配,如下所示:

#awk匹配包含root与user的行,匹配完root,再匹配user
[root@aminglinux-01 awk]# awk -F ':' '/root/ {print $1,$3} /user/ {print $1,$3,$4}' test.txt
root 0
operator 11
tss 59 59
user1 1001 1001
user2 1003 1003
user3 1004 1005
user4 1006 1005
user5 1007 1007
user6 1008 1010

#使用grep查找文件带有root与user的行
[root@xietaolinux1 awk]# grep -E 'root|user' test.txt 
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
user1:x:1010:1001::/home/user1:/bin/bash
user2:x:1002:1002::/home/user2:/bin/bash
user3:x:1003:1005::/home/user3:/bin/bash
user4:x:1006:1005::/home/aming111:/sbin/nologin
user5:x:1007:1007::/home/user5:/bin/bash
user6:x:1008:1010::/home/user6:/bin/bash


#与上条结果一致,使用复杂点
#使用awk打印出与上条grep打印出来一样的结果,包含root或者包含user的所有行.$0表示所有行
[root@ataolinux-01 awk]# awk -F ':' '/root|user/ {print $0}' test.txt   
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
user1:x:1001:1001::/home/user1:/bin/bash
user2:x:1002:1002::/home/user2:/bin/bash
user3:x:1004:1005::/home/user3:/bin/bash
user4:x:1006:1005::/home/aming111:/sbin/nologin
user5:x:1007:1007::/home/user5:/bin/bash
user6:x:1008:1010::/home/user6:/bin/bash
user7:x:1009:1009::/home/user7:/bin/bash
针对数学运算表达式,条件操作符

awk可以用逻辑符号进行判断,比如==就是等于,也可以理解为精确匹配,另外还有>、>=、<、<=、!=等,值得注意的是,在和数字比较时,若把比较的数字用双引号引起来,那么awk不会认为是数字,而会认为是字符,比较大小就是按 ASCII码的排序来,不加双引号则会认为是数字。

#直接把第三段等于0的行打印出来,这里需要写两个等于号,如果写一个等于号就相当于赋值,像之前学shell,给变量赋值就写了一个等于号
[root@aminglinux-01 awk]# awk -F ':' '$3==0' test.txt 
root:x:0:0:root:/root:/bin/bash

#匹配第三段中等于O的行,并打印第一段字符
[root@ataolinux-01 awk]# awk -F ':' '$3==0 {print $1}' test.txt 
root

#打印第三段大于等于1000的行,并打印第一段字符
[root@ataolinux-01 awk]# awk -F ':' '$3>=1000 {print $1}' test.txt
aming
user1
user2
user3
user4
user5
user6
user7

#数字用双引号引起来,是以ASCll的方式排序,awk会把所有的字符当作数字全部打印出来
[root@xietaolinux1 awk]# awk -F ':' '$3>="1000" {print $0}' test.txt 
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
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
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-bus-proxy:x:999:997:systemd Bus Proxy:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:998:996:User for polkitd:/:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
chrony:x:997:995::/var/lib/chrony:/sbin/nologin
aming:x:1000:1005::/home/aming:/bin/bash
user1:x:1010:1001::/home/user1:/bin/bash
user2:x:1002:1002::/home/user2:/bin/bash
user3:x:1003:1005::/home/user3:/bin/bash
user4:x:1006:1005::/home/aming111:/sbin/nologin
user5:x:1007:1007::/home/user5:/bin/bash
user6:x:1008:1010::/home/user6:/bin/bash

上例中,目的是想把uid大于等于1000的行打印出来,但是结果并不理想,这是因为awk把所有的数字当作字符了,就跟上一章中提到的sort排序原理一样,但如果不加双引号就得到了想要的结果,示例如下:

[root@aminglinux-01 awk]# awk -F ':' '$3>=1000 {print $0}' test.txt 
aming:x:1000:1005::/home/aming:/bin/bash
user1:x:1001:1001::/home/user1:/bin/bash
aminglinux:x:1002:1002::/home/aminglinux:/bin/bash
user2:x:1003:1003::/home/user2:/bin/bash
user3:x:1004:1005::/home/user3:/bin/bash
user4:x:1006:1005::/home/aming111:/sbin/nologin
user5:x:1007:1007::/home/user5:/bin/bash
user6:x:1008:1010::/home/user6:/bin/bash

!=表示不匹配,它除了针对某一个段的字符进行逻辑比较外,还可以在两个段之前进行逻辑比较,如下所示:

#第七段不等于sbin/nologin的字符,如果是字符串需要加双影号,不带空格
[root@aminglinux-01 awk]# awk -F ':' '$7!="/sbin/nologin" {print $0}' 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
aming:x:1000:1005::/home/aming:/bin/bash
user1:x:1001:1001::/home/user1:/bin/bash
aminglinux:x:1002:1002::/home/aminglinux:/bin/bash
user2:x:1003:1003::/home/user2:/bin/bash
user3:x:1004:1005::/home/user3:/bin/bash
user5:x:1007:1007::/home/user5:/bin/bash
user6:x:1008:1010::/home/user6:/bin/bash

两个字段之间做比较匹配

[root@aminglinux-01 awk]# awk -F ':' '$3<$4 {print $0}' test.txt 
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
aming:x:1000:1005::/home/aming:/bin/bash
user3:x:1004:1005::/home/user3:/bin/bash
user6:x:1008:1010::/home/user6:/bin/bash

[root@xietaolinux1 awk]# awk -F ':' '$3==$4' test.txt 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/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
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
user2:x:1002:1002::/home/user2:/bin/bash
user5:x:1007:1007::/home/user5:/bin/bash

另外还可以两个条件一起使用,使用&&和||,它们分别表示:“并且”和“或者”

&& 并且用法如下:

[root@aminglinux-01 awk]# awk -F ':' '$3>"5" && $3<"7"' test.txt 
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin

|| 或者用法如下:

精准,或者,精准等于
[root@aminglinux-01 awk]# awk -F ':' '$3>1000 || $7=="/sbin/nologin"' test.txt 
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
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-bus-proxy:x:999:997:systemd Bus Proxy:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:998:996:User for polkitd:/:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
chrony:x:997:995::/var/lib/chrony:/sbin/nologin
user1:x:1001:1001::/home/user1:/bin/bash
aminglinux:x:1002:1002::/home/aminglinux:/bin/bash
user2:x:1003:1003::/home/user2:/bin/bash
user3:x:1004:1005::/home/user3:/bin/bash
user4:x:1006:1005::/home/aming111:/sbin/nologin
user5:x:1007:1007::/home/user5:/bin/bash
user6:x:1008:1010::/home/user6:/bin/bash

精准,或者,匹配
[root@aminglinux-01 awk]# awk -F ':' '$3>1000 || $7 ~ /bash/' test.txt 
root:x:0:0:root:/root:/bin/bash
aming:x:1000:1005::/home/aming:/bin/bash
user1:x:1001:1001::/home/user1:/bin/bash
aminglinux:x:1002:1002::/home/aminglinux:/bin/bash
user2:x:1003:1003::/home/user2:/bin/bash
user3:x:1004:1005::/home/user3:/bin/bash
user4:x:1006:1005::/home/aming111:/sbin/nologin
user5:x:1007:1007::/home/user5:/bin/bash
user6:x:1008:1010::/home/user6:/bin/bash
awk的内置变量OFS

awk常用的变量有OFS、NF、NR,OFS和-F选项有类似的功能,也是和来定义分隔符的,但是它是在输出的时候定义,NF表示用分隔符分隔后一共有多少段,NR表示行号。

  • -F是指定匹配前的分隔符(分段前的分隔符)
  • OFS是用来指定print时候用到的分隔符

OFS的用法,先分隔,再单引号里边用花括号括起来给OFS指定print用到的那个分隔符,中间写条件,再写print语句,如果不写条件就是全部.

[root@xietaolinux1 awk]#  awk -F ':' '{OFS="#"} $3>1000 || $7 ~ /bash/ {print $1,$3,$7}' test.txt
root#0#/bin/bash
aming#1000#/bin/bash
user1#1010#/bin/bash
user2#1002#/bin/bash
user3#1003#/bin/bash
user4#1006#/sbin/nologin
user5#1007#/bin/bash
user6#1008#/bin/bash

#没有条件就是全部
[root@xietaolinux1 awk]#  awk -F ':' '{OFS="#"} {print $1,$3,$7}' test.txt
root#0#/bin/bash
bin#1#/sbin/nologin
daemon#2#/sbin/nologin
adm#3#/sbin/nologin
lp#4#/sbin/nologin
sync#5#/bin/sync
shutdown#6#/sbin/shutdown
halt#7#/sbin/halt
mail#8#/sbin/nologin
operator#11#/sbin/nologin
games#12#/sbin/nologin
ftp#14#/sbin/nologin
nobody#99#/sbin/nologin
systemd-bus-proxy#999#/sbin/nologin
systemd-network#192#/sbin/nologin
dbus#81#/sbin/nologin
polkitd#998#/sbin/nologin
tss#59#/sbin/nologin
postfix#89#/sbin/nologin
sshd#74#/sbin/nologin
chrony#997#/sbin/nologin
aming#1000#/bin/bash
user1#1010#/bin/bash
user2#1002#/bin/bash
user3#1003#/bin/bash
user4#1006#/sbin/nologin
user5#1007#/bin/bash
user6#1008#/bin/bash

#增加修饰符,定义完分隔符再定义OFS,后面条件可以与print一起写,这里用到了if,相当于一个整体.
[root@xietaolinux1 awk]# awk -F ':' '{OFS="#"} {if ($3>1000) {print $1,$2,$3,$4}}' test.txt 
user1#x#1010#1001
user2#x#1002#1002
user3#x#1003#1005
user4#x#1006#1005
user5#x#1007#1007
user6#x#1008#1010
awk的内置变量Nf

Nf的用法,表示多少段,$NF是最后一段的值,用法如下:

#打印这一行有多少段,并在开头显示出来
[root@aminglinux-01 awk]# 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-bus-proxy:x:999:997:systemd Bus Proxy:/:/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:998:996:User for polkitd:/:/sbin/nologin
7:tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
7:postfix:x:89:89::/var/spool/postfix:/sbin/nologin
7:sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
7:chrony:x:997:995::/var/lib/chrony:/sbin/nologin
7:aming:x:1000:1005::/home/aming:/bin/bash
7:user1:x:1001:1001::/home/user1:/bin/bash
7:aminglinux:x:1002:1002::/home/aminglinux:/bin/bash
7:user2:x:1003:1003::/home/user2:/bin/bash
7:user3:x:1004:1005::/home/user3:/bin/bash
7:user4:x:1006:1005::/home/aming111:/sbin/nologin
7:user5:x:1007:1007::/home/user5:/bin/bash
7:user6:x:1008:1010::/home/user6:/bin/bash
awk的内置变量NR

NR的用法,表示多少行.

#打印所有的行,这个就相当于grep -n功能,把行号显示出来
[root@aminglinux-01 awk]# 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-bus-proxy:x:999:997:systemd Bus Proxy:/:/sbin/nologin
15:systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
16:dbus:x:81:81:System message bus:/:/sbin/nologin
17:polkitd:x:998:996:User for polkitd:/:/sbin/nologin
18:tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
19:postfix:x:89:89::/var/spool/postfix:/sbin/nologin
20:sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
21:chrony:x:997:995::/var/lib/chrony:/sbin/nologin
22:aming:x:1000:1005::/home/aming:/bin/bash
23:user1:x:1001:1001::/home/user1:/bin/bash
24:aminglinux:x:1002:1002::/home/aminglinux:/bin/bash
25:user2:x:1003:1003::/home/user2:/bin/bash
26:user3:x:1004:1005::/home/user3:/bin/bash
27:user4:x:1006:1005::/home/aming111:/sbin/nologin
28:user5:x:1007:1007::/home/user5:/bin/bash
29:user6:x:1008:1010::/home/user6:/bin/bash

我们还可以使用NR与NF作为判断条件,如下所示:

NR作为判断条件

#打印小于等于10的行
[root@aminglinux-01 awk]# awk -F ':' 'NR<=10' test.txt 
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
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin

#两个条件一起使用,并且
[root@aminglinux-01 awk]# awk -F ':' 'NR<=10 && $1 ~ /root|sync/' test.txt 
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync

NF作为判断条件

[root@aminglinux-01 awk]# awk -F ':' 'NF==7 && $1 ~ /root|sync/' test.txt 
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync

这个$NR表示一共有多少行,从第一行到第七行都匹配打印出来,到了第八行就没有了,$NR没有了,因为一共就七段,你想打印第八段没有东西,就是空行了,而$NF一直都是七,相当于是$1$7,$2$7一直到$30$7结束,加上$跟不加是不一样的。

[root@xietaolinux1 awk]# awk -F ':' '{print $NR":"$NF}' test.txt
root:/bin/bash
x:/sbin/nologin
2:/sbin/nologin
4:/sbin/nologin
lp:/sbin/nologin
/sbin:/bin/sync
/sbin/shutdown:/sbin/shutdown
:/sbin/halt
:/sbin/nologin
:/sbin/nologin
:/sbin/nologin
:/sbin/nologin
:/sbin/nologin
:/sbin/nologin
:/sbin/nologin
:/sbin/nologin
:/sbin/nologin
:/sbin/nologin
:/sbin/nologin
:/sbin/nologin
:/sbin/nologin
:/bin/bash
:/bin/bash
:/bin/bash
:/bin/bash
:/sbin/nologin
:/bin/bash
:/bin/bash

总结:

awk是按行处理文件的,每一行都有awk内置变量:NF,NR

NF:是按给定的分隔符,分出来总的段数,所有$NF,指最后一段。

NR:是当前行的行号。$NR,表示第N行的第N段。

老师的示例中,每行有7段,所以,前面7行,第一列,分别显示当前行的段。如第一行显示第一段,第二行显示 第二段,第三行显示 第三段。。。。

awk可以更改段值 将第一段全部更改为root

一个与两个等于号相对应的功能

#两个等于是等于,只能把第一段匹配出来
[root@xietaolinux1 awk]# head -n 3 test.txt |awk -F ':' '$1=="root"'
root:x:0:0:root:/root:/bin/bash


#一个等于号相当于赋值了,一旦赋值后分隔符没有了。
[root@aminglinux-01 awk]# head -n 3 test.txt |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

#中间没有分隔符解决办法,定义OFS
[root@xietaolinux1 awk]# head -n 3 test.txt |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
awk的数学运算

awk还可以计算某个段的总和

#tot是指求和,
[root@aminglinux-01 awk]# awk -F ':' '{(tot=tot+$3)}; END {print tot}' test.txt 
11692

tot=tot+$3解释
这个tot值每一次循环都会把第三段的值相加,因为这个值之前不存在,默认为O,从O开始,第一次是0+$3,第二次第一行第三段加第二行的第三段,以此类推,加完后print tot求和。

这里的END是awk特有的语法,表示所有的行都已经执行,其实awk连同sed都可以写成一个脚本文件,而且有它们特有的语法,在awk中使用if判断、for循环都可以。

转载于:https://my.oschina.net/u/3708153/blog/2991709

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值