L28 Linux:awk的用法详解

来源:互联网 发布:软件研发部部门职责 编辑:程序博客网 时间:2024/05/22 09:04

awk比sed更加强大,它能做到sed能做到的,同样也能做到sed不能做到的。awk工具其实是很复杂的,有专门的书籍来介绍它的应用。

awk其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。实际上 AWK 的确拥有自己的语言: AWK 程序设计语言 , 三位创建者已将它正式定义为"样式扫描和处理语言"。它允许创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。

-F fs    fs指定输入分隔符,fs可以是字符串或正则表达式

-v var=value 赋值一个用户定义变量,将外部变量传递给awk

-f scripfile  从脚本文件中读取awk命令

-m[fr] val   对val值设置内在限制,-mf选项限制分配给val的最大块数目;-mr选项限制记录的最大数目。

常用功能实例:

1.截取文档中的某个段

head -n5 awk1.txt |awk -F ':' '{print $1}'

-F 选项的作用是指定分隔符,如果不加-F指定,则以空格或者tab为分隔符。 Print为打印的动作,用来打印出某个字段。$1为第一个字段,$2为第二个字段,依次类推,有一个特殊的那就是$0,它表示整行。

head -n5 awk1.txt |awk -F ':' '{print $0}'

awk {print $0} awk1.txt相当于cat awk1.txt

-F后紧跟单引号,然后里面为分隔符,print的动作要用 { } 括起来,否则会报错。print还可以打印自定义的内容,但是自定义的内容要用双引号括起来。

2.匹配字符或字符串

跟sed很类似,能实现grep的功能,但没有颜色显示,没有grep用起来方便。不过awk还有比sed更强大的匹配,可以让某个段去匹配,这里的'~'就是匹配的意思。

awk还可以多次匹配,如下图匹配完root,再匹配test,它还可以只打印所匹配的段。

egrep 'root|user' awk1.txt和awk -F ':' '/root|user/ {print $0}' awk1.txt效果是一样的。

3.条件操作符

[root@greg-01 ~/awk]# awk -F ':' '$3==0' awk1.txt

root:x:0:0:root:/root:/bin/bash

[root@greg-01 ~/awk]# awk -F ':' '$3==0 {print $1}' awk1.txt

root

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

加上双引号后,awk把所有的数字当作字符来对待了,就和 sort 排序原理一样,按照ASCII码比较。

除了针对某一个段的字符进行逻辑比较外,还可以两个段之间进行逻辑比较:

使用 && 和 || 表示 "并且" 和 "或者" 的意思。

[root@greg-01 ~/awk]# awk -F ':' '$3>1000 || $7=="/bin/bash"' awk1.txt

root:x:0:0:root:/root:/bin/bash

greg:x:1000:1006::/home/greg:/bin/bash

greg2:x:1001:1008::/home/greg2:/bin/bash

[root@greg-01 ~/awk]# awk -F ':' '$3>"5" && $3<"7"' awk1.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

4.awk常用的内置变量

$n 当前记录的第n个字段,比如n为1表示第一个字段,n为2表示第二个字段。

$0 这个变量包含执行过程中当前行的文本内容。

FILENAME 当前输入文件的名。

FS 字段分隔符(默认是任何空格)

NF 表示字段数,在执行过程中对应于当前的字段数。

NR 表示记录数,在执行过程中对应于当前的行号。

OFMT 数字的输出格式(默认值是%.6g)。

OFS 输出字段分隔符(默认值是一个空格)。

ORS 输出记录分隔符(默认值是一个换行符)。

RS 记录分隔符(默认是一个换行符)。

awk -F ':' '{print NR":"$0}' awk1.txt

awk -F ':' '{print NF":"$0}' awk1.txt

NF 是多少段,而$NF是最后一段的值, 而NR则是行号。

NR作为判断条件,也可以配合段匹配一起使用:

5.awk中的数学运算

awk可以把段值更改:

awk还可以对各个段的值进行数学运算:

还可以计算某个段的总和,比如第三段所有的和:

[root@greg-01 ~/awk]# awk -F ':' '{(tot=tot+$3)}; END {print tot}' awk1.txt

4665

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

[root@greg-01 ~/awk]# awk -F ':' '{if ($1=="root") {print $0}}' awk1.txt

root:x:0:0:root:/root:/bin/bash

练习:用awk 打印整个passwd wk '{print $0}' passwd查找所有包含 ‘bash’ 的行awk '/bash/' passwd用 ‘:’ 作为分隔符,查找第三段等于0的行awk -F':' '$3=="0"' passwd用 ‘:’ 作为分隔符,查找第一段为 ‘root’ 的行,并把该段的 ‘root’ 换成 ‘toor’ (可以连同sed一起使用)awk -F':' '$1=="root"' passwd |sed 's/root/toor/'用 ‘:’ 作为分隔符,打印最后一段awk -F':' '{print $NF}' passwd打印行数大于20的所有行awk -F':' 'NR>20' passwd用 ‘:’ 作为分隔符,打印所有第三段小于第四段的行awk -F':' '$3<$4' passwd用 ‘:’ 作为分隔符,打印第一段以及最后一段,并且中间用 ‘@’ 连接 (例如,第一行应该是这样的形式 'root@/bin/bash‘ )awk -F':' '{print $1"@"$NF}' passwd用 ‘:’ 作为分隔符,把整个文档的第四段相加,求和awk -F':' '{(sum+=$4)}; END {print sum}' passwd


原创粉丝点击