简介

awk 命令可以同时传入两个文件,这使得利用一个文件构建键值对,再用另一个文件的进行索引。这有些类似于 look up,但更类似于 数据补全:列操作

情景

文件 A:

AT1G01010.1     1688
AT1G01020.1     3832
AT1G01020.2     1319
AT1G01020.3     560
AT1G01020.4     1532
AT1G01020.5     96
AT1G01020.6     144
AT1G01030.1     1525
AT1G01030.2     2216
AT1G01040.1     10733

文件 B:

AT1G01010       NAC001  3631-5899
AT1G01020       ARV1    6788-9130
AT1G01030       NGA3    11649-13714
AT1G01040       DCL1    23121-31227
AT1G01050       PPa1    31170-33171
AT1G01060       LHY     33365-37871
AT1G01070       UMAMIT28        38444-41017
AT1G01080       AT1G01080       44970-47059
AT1G01090       PDH-E1 ALPHA    47234-49304
AT1G01100       AT1G01100       49909-51210

需求:按基因 ID,将文件 B 中的基因名(2)和基因位置(\3)匹配至文件 A 中

实现

使用 awk 命令,编写 awk 脚本如下

BEGIN {                                 # begin块:用于初始化输入输出分隔符
	FS = "\t"
	OSF = "\t"
}
NR == FNR {                             # 匹配条件:行号 == 当前处理总行数,即处理第一个文件时执行
	geneName[$1] = $2                   # 基因ID为键,基因名为值
	geneLocation[$1] = $3               # 基因ID为键,基因位置为值
	next                                # 注意!awk的默认行为是打印,使用next跳过打印行为
}
{                                       # 匹配条件:行号 != 当前处理总行数,即处理第二个文件时执行
	split($1, arr, ".")                 # 拆分转录本ID
	geneID = arr[1]                     # 取前缀
	print($0, genName[geneID], geneLocation[geneID])            # 输出整行与匹配的值
}
awk -f script.awk fileB fileA # 注意传入文档的顺序,先建立关联数组再进行索引