在下面的awk
中,我正在尝试打印$10
= reference standard
和$3
值匹配的行。我的实际数据是几千tab-delimited
行,因此输入和输出都设置为tab-delimited
。谢谢你:)。
AWK
awk -F'\t' -v OFS='\t' 'FNR==NR{a[$0];next} $(NF-1)$NF=="referencestandard" && {A[$3];next}$3 in A in a{print}' file
awk: cmd. line:1: FNR==NR{a[$0];next} $(NF-1)$NF=="referencestandard" && {A[$3];next}$3 in A in a{print}
awk: cmd. line:1: ^ syntax error
文件
#tax_id GeneID Symbol RSG LRG RNA t Protein p Category
9606 4200 ME2 NG_016198.1 NM_002396.4 NP_002387.1 reference standard
9606 2122 MECOM NG_028279.1 NM_004991.3 NP_004982.2 reference standard
9606 4204 MECP2 NG_007107.2 NM_004992.3 NP_004983.1 reference standard
9606 4204 MECP2 NG_007107.2 NM_001110792.1 NP_001104262.1 reference standard
期望的输出
9606 4204 MECP2 NG_007107.2 NM_004992.3 NP_004983.1 reference standard
9606 4204 MECP2 NG_007107.2 NM_001110792.1 NP_001104262.1 reference standard
答案 0 :(得分:2)
对于几千行,最简单的方法是处理数据文件(我的名称为data
)两次 - 在命令行上列出两次。在第一次传递时,记录$3
值出现的次数,最后一个字段设置为'参考标准'。在第二遍中,打印这些记录,将最后一个字段设置为'参考标准'以及$3
大于1
的出现次数:
awk -F'\t' -v OFS='\t' \
'FNR == NR && $NF == "reference standard" { a[$3]++; next }
a[$3] > 1 && $NF == "reference standard" { print }' data data
对于样本数据,我得到的输出是:
9606 4204 MECP2 NG_007107.2 NM_004992.3 NP_004983.1 reference standard
9606 4204 MECP2 NG_007107.2 NM_001110792.1 NP_001104262.1 reference standard
这种技术可以避免将文件的整个副本保留在内存中,并解决其他一些簿记问题。由于您的代码已经具有FNR==NR
模因,我认为您在这些方面有所考虑,即使您没有在命令行上重复文件名。
如果您能够将整个文件保存在内存中(或者它来自管道而不是文件,因此您无法重新扫描它),您可以通过以下单个传递来完成:
awk -F'\t' -v OFS='\t' \
'FNR==NR && $NF == "reference standard" {
index = a[$3]++; line[NR] = $0; reps[$3,index] = NR; next
}
END { for (i in a)
if (a[i] > 1)
for (j = 0; j < a[$3]; j++)
print line[reps[i,j]]
}' data
当然,这会产生相同的输出。缺点是你有一个内存中的完整数据集的副本,以及各种控制数组,所以它使用的内存比双通道更多。