awk打印匹配的行并在字段中具有特定值

时间:2016-11-28 23:01:42

标签: awk

在下面的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

1 个答案:

答案 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

当然,这会产生相同的输出。缺点是你有一个内存中的完整数据集的副本,以及各种控制数组,所以它使用的内存比双通道更多。