awk 介绍
awk 是Linux下常用的文本处理命令,它名字取自1977年最初三个开发人员的首字母,他们是: Alfred Aho、Peter Weinberger、Brian Kernighan,他们三人是AT&T贝尔实验室的Unix开发人员。
使用方法
先看一下官方的描述
awk - pattern-directed scanning and processing language
awk 是一种基于样式的文本扫描和处理工具,它的使用方法如下:
1 | $ awk [ -F fs ] [ -v var=value ] [ 'prog' | -f progfile ] [ file ... ] |
用单引号引起来的部分称为 programs,包括样式和动作两个部分。看下面一个简单的例子,这个例子将 who
命令输出的内容第一列打印出来。
1 | $ who |
awk 处理文本以行为单位,默认情况下处理所有行的文本,上面例子中有两行文本,全部进行了处理。默认情况下,awk 采用空格来分割单词,$1
表示按照空格分割后的第1个单词。$NF
表示最后一个单词。根据需要,我们可以打印一个或多个单词。
1 | $ cat dennis-ritchie.txt |
如果想将输入的内容用连接字符接起来,可以使用 OFS
参数(Output Field Separator)。
1 | $ date |
BEGIN 和 END
我们常有一些在文本出来开始之前的准备工作,或者文本处理完成之后的总结工作,利用 BEGIN\END
这两个规则可以快速的满足需求。awk 支持多个BEGIN或END,并按照他们的顺序依次执行。
1 | $ who |
单词分隔符
有些文件中的单词或数据并不以空格分割,例如 /etc/passwd
文件或者一些 csv 文件。我们可以使用 -F
参数指定分割字符串。
1 | $ awk -F: '{print $1,$5}' /etc/passwd |
增加Pattern
1 | $ awk '[ pattern ] {action}' [ filename ... ] |
如果需要对 action 的内容做过滤,可以添加 pattern。如下例,在 /etc/passwd 文件中,将UID大于1000的用户打印出来。
1 | $ awk -F: '$3 >= 1000 {print $1,$6}' /etc/passwd |
还可以利用 BEGIN 命令,打印一个简单的表头。
1 | $ awk -F: 'BEGIN {print "User Accounts\n-------------"} $3 >= 1000 {print $1,$6}' /etc/passwd |
Pattern 支持正则的全部功能,因此可以用正则表达式来设置过滤规则。如下例为过滤包含key的单词,并把整行文本打印出来。
1 | $ awk '/key/ {print $0}' /tmp/1.plist |
内置函数
awk 提供了很多内置函数,包括数学运算、字符串处理、时间计算、类型转换等丰富的功能。如下示例展示了数学运算的函数。
1 | $ awk 'BEGIN { print sqrt(625)}' |
awk 脚本
如果要处理的任务非常复杂,单靠写命令行命令就不太适用,这时可采用 awk 脚本来提高效率。
先看下面一个例子
1 |
|
将内容保存为 awk.sh 文件,看一下执行效果
1 | $ chmod +x awk.sh |
常用命令
本文总结了AWK的一些常见用法。
1、打印文件的前两列(空格为分隔符)
1 | $ awk ‘{print $1,$2}’ awkfile |
2、逗号为分隔符,打印指定的列
1 | $ awk -F , '{print $1,$2,$20,$21,$22}' n_epm_user.sql |
3、逗号为分隔符,打印符合条件的记录
1 | $ awk -F , '{if ($20==1) print $1,$2,$20,$21,$22}' n_epm_user.sql |
4、取文件的第五列,并且将部分内容替换为空
1 | $ awk '{print gensub(/\/data1\/static\.house\.sina\.com\.cn\/cricfs\//,"","g",$5) }' /data1/logs |