awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
使用方法 : awk ‘{pattern + action}’ {filenames}
尽管操作可能会很复杂,但语法总是这样,其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号({})不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。 pattern就是要表示的正则表达式,用斜杠括起来。
awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作。完整的awk脚本通常用来格式化文本文件中的信息。通常,awk是以文件的一行为处理单位的。awk每接收文件的一行,然后执行相应的命令,来处理文本。

常见参数:

-F,fields,设置字段分隔符;
-v,var=value 定义awk程序中的一个变量及其默认值
image.png

  1. awk 'BEGIN{print “find UTR feature”} /UTR/{print $0} END{print "END"} '

awk 在读取一行文本时,会用预定义的字段分隔符划分每个
数据字段,并分配给一个变量。
$0 代表整个文本行;
$1 代表文本行中的第1个数据字段;
……
$NF 代表文本行中的最后一个数据字段
awk 默认的字段分隔符是任意空白字符(如:空格 or 制表
符),也可以用 -F 参数自定义分隔符

awk - 图2

awk内置变量

  1. ARGC 命令行参数个数
  2. ARGV 命令行参数排列
  3. ENVIRON 支持队列中系统环境变量的使用
  4. FILENAME awk浏览的文件名
  5. FNR 浏览文件的记录数
  6. FS 设置输入域分隔符,等价于命令行 -F选项
  7. NF 浏览记录的域的个数 ##列数
  8. NR 已读的记录数 ##行数
  9. OFS 定义输出列分隔符
  10. ORS 定义输出记录分隔符
  11. RS 控制记录分隔符
  12. $0变量是指整条记录。$1表示当前行的第一个列,$2表示当前行的第二个域,......以此类推。
  13. $NFnumber finally,表示最后一列的信息,跟变量NF是有区别的,变量NF统计的是每行列的总数

常用的命令展示

awk擅长列输出
搜索/etc/passwd有root关键字的所有行

  1. awk '/root/' /etc/passwd 【这种是pattern的使用,匹配了pattern(这里是root)的行才会执行action(没有指定action,默认输出每行的内容)】

搜索/etc/passwd有root关键字的所有行,并显示对应的shell
**

  1. awk -F: '/root/ {print $7}' /etc/passwd

统计/etc/passwd:文件名,每行的行号,每行的列数,对应的完整行内容:

  1. awk -F ':' '{printf("filename:%10s,linenumber:%3s,column:%3s,countent:%3f\n",FILENAME,NR,NF,$0)}' /etc/passwd

使用printf替代print,可以让代码更加简洁,易读

  1. awk -F: '{printf ("filename:%10s, linenumber:%3s,column:%3s,content:%3f\n",FILENAME,NR,NF,$0)}' /etc/passwd

打印/etc/passwd/的第二行信息

  1. awk -F: 'NR==2{print "filename: "FILENAME, $0}' /etc/passwd

awk的过滤使用方法

  1. ls -lF | awk '/^d/'

指定特定的分隔符,查询第一列

  1. awk -F ":" '{print $1}' /etc/passwd

指定特定的分隔符,查询最后一列

  1. awk -F ":" '{print $NF}' /etc/passwd

指定特定的分隔符,查询倒数第二列

  1. 指定特定的分隔符,查询倒数第二列

获取第12到31行的第一列的信息

  1. awk -F ":" '{if(NR<31 && NR >12) print $1}' /etc/passwd

去除文件header

  1. awk 'NR>1' gene.bed # 等价于
  2. awk 'NR>1{print}' gene.bed # 又等价于
  3. awk 'NR>1{print $0}' gene.bed

打印一定区间内的行

  1. # 打印3-6行的基因信息,&&是逻辑运算符“且”
  2. awk 'NR>2&&NR<7' gene.bed

删除空行

  1. awk 'NF' gene.bed

提取字段

  1. # 提取第一和第二个字段
  2. awk 'BEGIN{FS=OFS="\t"} {print $1,$2}' gene.bed

有空格??加上NF变量去除即可

  1. awk 'BEGIN{FS=OFS="\t"} NF{print $1,$2}' gene.bed

还需要跳过header??一起来试试吧。

  1. awk 'BEGIN{FS=OFS="\T"} NF&&NR>1{print $1,$2}' gene.bed

实现列运算,小需求:统计文件中各类型基因总数

  1. awk 'BEGIN{FS=OFS="\t"} {sum+=$2} END{print sum}' gene_type.txt
  2. # 1842

我们的需求是统计每一类别基因的数目

  1. awk 'BEGIN{FS=OFS="\t"} NR>1{sum[$1]+=$2} END{for(i in sum) print i,sum[i]}' gene_type.txt

awk中的数组

数组是AWK的一个强大特性。AWK中的所有数组都是关联数组,因此允许将任意字符串与另一个值关联起来。如果你熟悉其他编程语言,可能会知道数组是散列、关联表、字典或映射。
从表面上看,awk中的数组类似于其他编程语言中的数组,但它们有根本的区别。在awk中,在开始使用数组之前没有必要指定数组的大小。此外,任何数字或字符串,而不仅仅是连续整数,都可以用作数组索引。并且,awk中数组不需要提前声明,这避免了为数组提前分配一个连续的内存块。但是同其他语言一样,awk 索引非负,从0开始。

需要将fasta格式的多行核酸序列转换为一行,

  1. awk '{if(/^>/) id=$0;else seq[id]=seq[id]$0} END{for(i in seq) print i"\n"seq[i]}' dna.fa

awk 条件和循环语句:
if:条件判断
awk ‘ { if (判断条件) {yes}**else {no} } ‘
for:循环语句
awk ‘ { for (循环条件) {循环语句} } **

  1. awk '{if ($3=="gene") print $0}'
  2. awk '{if ($3=="gene") print $0} else{print $3 "is not hene"}}'

awk 数学运算:
+ (加),- (减), (乘),^ (幂) / (除),* (平方), % (取余) int(x) x的整数部分,取靠近零一侧的值 log(x) x的自然对数

  1. awk '/exon/{print $5-$4}'
  2. awk '{print $5/$4}'

awkshell脚本

  1. awk 'BEGIN{ i=0 } { i++ } END{ print i }' filename