awk:强大的文本分析工具

2022-05-05 13:13:18 浏览数 (1)

在上一期的文章sed:小工具大用处中小编为大家介绍了sed的使用方法,今天继续为大家介绍另一个非常常用的工具awk。祖国70周年生日在即,为了不给祖国拖后腿,抓紧时间最后再努力学习一把!

awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格或tab为默认分隔符将每行切片,切开的部分再进行各种分析处理。awk可以处理文件数据,或者来自前个命令的标准输入内容,awk的一般使用规则如下:

代码语言:javascript复制
awk -Ffv 'BEGIN{} //条件{动作1;动作2} END {}' 文件或标准输入

大参数:参数-F指定分隔符,-f调用脚本,-v定义变量;

BEGIN 初始化代码块,在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符

// 匹配代模块,可以是字符串或正则表达式

{} 命令代模块,包含一条或多条命令

; 多条命令使用分号分隔

END 结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息

01

数据内容选取

我们可以使用匹配模块搭配正则表达式选取行:

其中匹配内容里面可以使用bash变量,但是必须用加单引号,如下所示:

我们也可以根据分隔符选取字段,例如使用last列出最后五行登陆者信息,并使用awk中print命令选取账户名及其IP信息:

其中“t”表示分隔符为tab,注意这里是打印内容的分隔符,而不是划分域的分隔符,可以换成其他符号甚至是任意字符串(包括数据)均可:

最后一行是时间信息,中间隔着一行空行,如要是进一步只选取账户和IP可以使用sed命令:

由以上例子可以看出awk工作流程:读入有'n'换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,0则表示所有域,1表示第一个域,n表示第n个域。默认域分隔符是空格键或[tab]键,所以1表示登录用户,

可以使用-F强制制定其他划分域的分隔符,多个分隔符使用[]括起来:

这里需要注意"/:"和"[/:]"的不同。这个功能在处理物种分类信息的时候非常有用,例如多样性分析中otutable的物种注释信息各个水平堆叠在一起,不利于作图:

我们可以从中选取科水平的注释结果:

提取的结果可以保存到文件:

保存的文件可以安行和原来的otu table进行合并(使用paste命令)。

02

内置变量

awk有许多内置变量用来设置环境信息,这些变量可以被改变,下面给出了最常用的一些变量:

ENVIRON 支持队列中系统环境变量的使用

FILENAME awk浏览的文件名,对于批量处理文件很有用

FNR 浏览文件的次数,一般与NR相同,大于NR处理多个文件

FS 设置输入域分隔符,等价于命令行-F选项

NF 浏览记录的域的个数

NR 已读的记录数,可以指定处理某一行

OFS 输出域分隔符

ORS 输出记录分隔符

RS 控制记录分隔符

下面我们利用内置变量来处理数据信息:

在上面例子中,我们使用内置变量显示了行号以及每一行的字段数目。

03

条件运算符

awk的命令间也可以使用条件运算符设置条件类型,使得命令选择性执行,常见的有大于>、小于<、大于等于>=、小于等于<=、等于==、不等于!=、匹配~、不匹配!~。下面我们以/etc/passwd文件为例,这个文件每一行字段之间以“:”分割,如下所示:

接下来我们选取第三个字段也即UID大于500小于600的数据行,并且列出每行第一字段账号和第三字段UID:

可以发现,条件类型里还可以使用逻辑连接符。awk的这种数据筛选功能也非常有用,例如可以用来筛选高丰度的物种或者基因。

04

AWK编程

awk的条件类型决定着动作命令的执行,其条件语句可以通过变量以及判断语句进行编程实现,还可以搭配正则表达式。

除了awk自定义的变量,用户可以根据需要自定义变量,例如我们可以通过自定义变量计算文件的行数:

在这里count=count 1可以简写为count =1,或者count ,同理每次加2则表示为count =2。上面命令的另一种写法为:

代码语言:javascript复制
awk 'BEGIN{count=0} {count=count 1} END{print "user count is ", count}' /etc/passwd

awk同样可使用if控制结构,例如前面计算序列总数的命令使用if结构如下:

要注意if() {} else {}是一个完整的结构,要放在一个花括号内。

awk同样可以引入数组以及for结构。awk中的数组下标可以是数字和字母,数组的下标通常被称为关键字(key)。下面通过两个例子比较说明:

代码语言:javascript复制
①awk -F ':' 'BEGIN{count=1} {name[count]=$1;count  } END{for (i=1; i<=NR; i  ) print i, name[i]}' /etc/passwd
②last -n 100 | sed -n '1,100p' | awk '{a[$1]  } END{for (i in a) print i,"t", a[i]}'

第一个例子中,定义了name[count]数组,for为迭代循环,因为数组的下标是从1开始的整数,通过迭代打印出对应的下标以及数组内容。第二个例子中定义了关联数组a[1](参照Perl语言中的哈希),其下标是key(既可能是数字也可能是字母,没有规则)不需要定义初值,通过for循环结构打印出结果。a[1] 实质为计算

0 人点赞