简介
awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
使用方法
awk '{pattern + action}' {filenames}
awk工作流程是这样的:先执行BEGING,然后读取文件,读入有/n换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域,随后开始执行模式所对应的动作action。接着开始读入第二条记录······直到所有的记录都读完,最后执行END操作。
尽管操作可能会很复杂,但语法总是这样,其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号({})不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。 pattern就是要表示的正则表达式,用斜杠括起来。
awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作。完整的awk脚本通常用来格式化文本文件中的信息。
通常,awk是以文件的一行为处理单位的。awk每接收文件的一行,然后执行相应的命令,来处理文本。
1. 开始
从最简单的例子开始:
$ awk '{print $1, $4}' file.txt
上面的命令作用是输出file.txt文件中的第1列和第4列
- awk后的命令用单引号
- 其中$1, $2…表示第几列,$0表示整行
awk中同时提供了print和printf两种打印输出的函数。
其中print函数的参数可以是变量、数值或者字符串。字符串必须用双引号引用,参数用逗号分隔。如果没有逗号,参数就串联在一起而无法区分。这里,逗号的作用与输出文件的分隔符的作用是一样的,只是后者是空格而已。
printf函数,其用法和c语言中printf基本相似,可以格式化字符串,输出复杂时,printf更加好用,代码更易懂。
$ awk '{printf "%-8s %-8s %-22s\n",$1,$2,$3}' file.txt
筛选
下面的筛选条件是第3行等于0 && 第6行的值为LISTEN:
$ awk '$3==0 && $6=="LISTEN" ' file.txt
其中的“==”为比较运算符。其他比较运算符:!=, >, <, >=, <=。
&&为逻辑运算符,此外还可以用||。
内建变量
变量 | 含义 |
---|---|
$0 | 当前记录(这个变量中存放着整个行的内容) |
$1~$n | 当前记录的第n个字段,字段间由FS分隔 |
FS | 输入字段分隔符 默认是空格或Tab |
OFS | 输出字段分隔符, 默认也是空格 |
RS | 输入的记录分隔符, 默认为换行符 |
ORS | 输出的记录分隔符,默认为换行符 |
NF | 当前记录中的字段个数,就是有多少列 |
NR | 已经读出的记录数,就是行号,从1开始,如果有多个文件话,这个值也是不断累加中。 |
FNR | 当前记录数,与NR不同的是,这个值会是各个文件自己的行号 |
FILENAME | 当前输入文件的名字 |
awk默认的分隔符为空格或TAB(FS变量),在使用的时候可以改变:
awk 'BEGIN{FS=":"} {print $1,$3,$6}' /etc/passwd
上面的命令也等价于
$ awk -F: '{print $1,$3,$6}' /etc/passwd
-F的意思就是指定分隔符,当然也可以指定多个分隔符
$ awk -F '[;:]'
再来看一个以\t作为分隔符输出的例子(下面使用了/etc/passwd文件,这个文件是以:分隔的):
$ awk -F: '{print $1,$3,$6}' OFS="\t" /etc/passwd
模式匹配
$ awk '$6 ~ /FIN|TIME/ || NR==1 {print NR,$4,$5,$6}' netstat.txt
- ~表示模式开始
- /…/两个斜线之间是模式,也就是正则表达式
- | 表示多个模式或的关系 , || 表示条件或
- 还可以用!取反
脚本
AWK有两个关键字BEGIN和END,意味着执行前和执行后的意思,语法如下:
- BEGIN{ 这里面放的是执行前的语句 }
- END {这里面放的是处理完所有的行后要执行的语句 }
- {这里面放的是处理每一行时要执行的语句}
调用AWK的三种方法
- 命令行
- 脚本,首行换成#!/bin/awk
- 所有的awk命令插入一个单独文件,然后调用:
"-f参数为加载script-file.awk文件中的awk脚本
$ awk -f script-file.awk input-file(s)
AWK编程
除了awk的内置变量,awk还可以自定义变量,下面统计/etc/passwd的账户人数:
$ awk '{count++;print $0;} END{print "user count is ", count}' /etc/passwd
条件语句和循环语句都借鉴了C语言中的关键字和语法。
awk中数组的下标可以是数字和字母,数组的下标通常被称为关键字(key)。值和关键字都存储在内部的一张针对key/value应用hash的表格里。由于hash不是顺序存储,因此在显示数组内容时会发现,它们并不是按照你预料的顺序显示出来的。数组和变量一样,都是在使用时自动创建的,awk也同样会自动判断其存储的是数字还是字符串。一般而言,awk中的数组用来从记录中收集信息,可以用于计算总和、统计单词以及跟踪模板被匹配的次数等等。