awk 工具的使用
awk:针对文档中的行来操作,一行一行地执行。
截取文档中的某个段**
示例:
[root@jinkai01 sed]# head -n2 passwd | awk -F ':' '{print $1}'
roto
bin
-F选项的作用是指定分隔符。如果不加-F选项,则以空格或者tab为分隔符。print为打印的动作,用来打印某个字段。
$1为第1个字段,$2为第2个字段,以此类推。但$0比较特殊,它表示整行:
[root@jinkai01 sed]# head -n2 passwd | awk -F ':' '{print $0}'
roto:x:0:0:roto:/roto:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
1,匹配字符或者字符串
打印出passwd 文件中包含 oo 的行
[root@jinkai01 awk]# awk '/oo/' passwd
打印出passwd 文档中以:为分隔符的第一列包含有oo 的行
[root@jinkai01 awk]# awk -F ':' '$1 ~ /oo/' passwd
root:x:0:0:root:/root:/bin/bash
2,还可以一次性匹配多个字符串
打印出passwd 文档中以:为分隔符包含root或user的第一列和第三列
[root@jinkai01 awk]# awk -F ':' '/root/ {print $1,$3} /user/ {print $1,$3}' passwd
条件操作符
awk中可以用逻辑符号进行判断,比如==就是等于,也可以理解为精确匹配。另外还有>、>=、<、<=、!=等。
值得注意的是,在和数字比较时,若把比较的数字用双引号引起来,那么awk不会认为是数字,而会认为是字符,按照ACSII进行比较;不加双引号则会认为是数字,按照数字大小比较;
[root@jinkai01 awk]# awk -F ':' '$3>=500' passwd
[root@jinkai01 awk]# awk -F ':' '$3>=500' passwd
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
linuxprobe:x:1000:1000:linuxprobe:/home/linuxprobe:/bin/bash
加双引号,以ACSII码值进行比较
[root@jinkai01 awk]# awk -F ':' '$3>="500"' passwd
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
nobody:x:99:99:Nobody:/:/sbin/nologin
除了针对某一个段的字符进行逻辑比较外,还可以在两个段之间进行
逻辑比较。
打印出passwd 文档中 第三列数值小于第四列
[root@jinkai01 awk]# awk -F ':' '$3<$4' passwd
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
另外还可以使用&&和||,它们分别表示“并且”和“或者”。
打印出passwd 文档中第三列数值小于7大于5的行
[root@jinkai01 awk]# awk -F ':' '$3>5 && $3<7' passwd
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
打印出passwd 文档中第三列大于1000 或者第七列是/bin/bash的行
[root@jinkai01 awk]# awk -F ':' '$3>1000 || $7=="/bin/bash"' passwd
root:x:0:0:root:/root:/bin/bash
linuxprobe:x:1000:1000:linuxprobe:/home/linuxprobe:/bin/bash
user1:x:1001:1001::/home/user1:/bin/bash
user2:x:1002:1002::/home/user2:/bin/bash
awk 的内置变量
awk常用的变量有OFS、NF和NR,OFS和-F选项有类似的功能,也是用来定义分隔符的,但是它是在输出的时候定义,NF表示用分隔符分隔后一共有多少段,NR表示行号。
OFS的用法示例如下:
打印出passwd 文档中以:为分隔符的第一,三,四列,并且以#号为分隔符
[root@jinkai01 awk]# head -5 passwd | awk -F ':' '{OFS="#"} {print $1,$3,$4}'
root#0#0
bin#1#1
daemon#2#2
打印出passwd 文档中以:为分隔符,第三列大于1000的行,然后打印出其中的第1,2,3,4列,且重新以#号为分隔符
[root@jinkai01 awk]# awk -F ':' '{OFS="#"} {if ($3>1000) {print $1,$2,$3,$4}}' passwd
user1#x#1001#1001
user2#x#1002#1002
变量NF的具体用法如下:
NF为列,下面是查询passwd 文档以:为分隔符总共有几列
[root@jinkai01 awk]# head -3 passwd |awk -F ':' '{print NF}'
7
7
7
这里NF是多少段,$NF是最后一段的值。
[root@jinkai01 awk]# head -3 passwd |awk -F ':' '{print $NF}'
/bin/bash
/sbin/nologin
/sbin/nologin
变量NR的具体用法如下:
NR为行,打印出行号
[root@jinkai01 awk]# head -3 passwd |awk -F ':' '{print NR}'
1
2
3
还可以使用NR作为判断条件
将passwd文档中行号大于18的行打印出来
[root@jinkai01 awk]# cat passwd | wc -l
21
[root@jinkai01 awk]# awk 'NR>18' passwd
linuxprobe:x:1000:1000:linuxprobe:/home/linuxprobe:/bin/bash
user1:x:1001:1001::/home/user1:/bin/bash
user2:x:1002:1002::/home/user2:/bin/bash
NR也可以配合段匹配一起使用,如下所示:
将passwd 文档中以:为分隔符,行号小于20 并且第一列为root的行打印出来
[root@jinkai01 awk]# awk -F ':' 'NR<20 && $1 ~ /root/' passwd
root:x:0:0:root:/root:/bin/bash
awk 中的数学运算
awk可以更改段值,示例命令如下:
将passwd文档中以:为分隔符,第一列改成 root。
=一个等号是赋值,==两个等号才是等于;
[root@jinkai01 awk]# head -n 3 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
awk也可以对各个段的值进行数学运算,示例命令如下:
将passwd文档中,以:号为分隔符,将第七列赋值为第三列和第四列的和
[root@jinkai01 awk]# head -2 passwd | awk -F ':' '{$7=$3+$4; print $0}'
root x 0 0 root /root 0
bin x 1 1 bin /bin 2
awk还可以计算某个段的总和,示例命令如下:
tot 为上一次tot值加下一行第三列的值,最开始tot为零,循环匹配到最后一行第三列,然后打印出总和值
END是awk特有的语法,表示所有的行都已经执行。
[root@jinkai01 awk]# awk -F ':' '{(tot=tot+$3)}; END {print tot}' passwd
4610
课后习题
(1) 用awk打印整个test.txt。(以下操作都是针对test.txt的,用awk工具实现。)
awk '{print $0}' test.txt
(2) 查找所有包含bash的行。
awk '/bash/' test.txt
(3) 用:作为分隔符,查找第3个字段等于0的行。
awk -F':' '$3=="0"' test.txt
(4) 用:作为分隔符,查找第1个字段为root的行,并把该段的root换成toor。(可以连同sed一起使
用。)
awk -F':' '$1=="root"' test.txt |sed 's/root/toor/'
(5) 用:作为分隔符,打印最后一个字段。
awk -F':' '{print $NF}' test.txt
(6) 打印行数大于20的所有行。
awk -F':' 'NR>20' test.txt
(7) 用:作为分隔符,打印所有第3个字段小于第4个字段的行。
awk -F':' '$3<$4' test.txt
(8) 用:作为分隔符,打印第1个字段以及最后一个字段,并且中间用@连接(例如,第1行应该是
这样的形式:root@/bin/bash)。
awk -F':' '{print $1"@"$NF}' test.txt
(9) 用:作为分隔符,把整个文档的第4个字段相加,求和。
awk -F':' '{(sum+=$4)}; END {print sum}' test.txt