L28 Linux:awk的用法详解
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.条件操作符
[aaa@qq.com ~/awk]# awk -F ':' '$3==0' awk1.txt
root:x:0:0:root:/root:/bin/bash
[aaa@qq.com ~/awk]# awk -F ':' '$3==0 {print $1}' awk1.txt
root
awk中是可以用逻辑符号判断的,比如 '==' 就是等于,也可以理解为 '精确匹配' 另外也有 >, '>=, '<, '<=, '!= 等等,值得注意的是,在和数字比较时,若把比较的数字用双引号引起来,那么awk不会认为是数字,而认为是字符,不加双引号则会认为是数字。
加上双引号后,awk把所有的数字当作字符来对待了,就和 sort 排序原理一样,按照ASCII码比较。
除了针对某一个段的字符进行逻辑比较外,还可以两个段之间进行逻辑比较:
使用 && 和 || 表示 "并且" 和 "或者" 的意思。
[aaa@qq.com ~/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
[aaa@qq.com ~/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还可以对各个段的值进行数学运算:
还可以计算某个段的总和,比如第三段所有的和:
[aaa@qq.com ~/awk]# awk -F ':' '{(tot=tot+$3)}; END {print tot}' awk1.txt
4665
END表示所有的行都已经执行,这是awk特有的语法,其实awk连同sed都可以写成一个脚本文件,而且有他们特有的语法,在awk中使用if判断、for循环都是可以的。如下:
[aaa@qq.com ~/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
用 ‘:’ 作为分隔符,打印第一段以及最后一段,并且中间用 ‘@’ 连接 (例如,第一行应该是这样的形式 'aaa@qq.com/bin/bash‘ )
awk -F':' '{print $1"@"$NF}' passwd
用 ‘:’ 作为分隔符,把整个文档的第四段相加,求和
awk -F':' '{(sum+=$4)}; END {print sum}' passwd
下一篇: MySQL count知多少
推荐阅读
-
L28 Linux:awk的用法详解
-
Linux cat test.txt | while read line, read 命令详解, if 多条件 -a 使用,简单的用户登录程序
-
Unity C# 《有限状态机》的用法教程详解
-
【转载】Linus下的/etc/hosts文件详解 博客分类: Linux/Win 网络配置host文件
-
详解远程桌面协议, Linux 和 Windows 间的远程桌面互相访问(RDP、VNC协议)
-
linux—Centos7系统不同虚拟机之间的免密登录设置详解及问题剖析
-
PHP数字前补0的自带函数sprintf 和number_format的用法(详解)
-
PHP封装的多文件上传类实例与用法详解
-
详解Java中Iterator迭代器的用法
-
Yii2中hasOne、hasMany及多对多关联查询的用法详解