2016-11-28 169 views
0

在下面的awk我试图打印$10 = reference standard$3值匹配的行。我的实际数据是几千行tab-delimited,所以输入和输出都设置为tab-delimited。谢谢 :)。awk打印行匹配并在字段中具有特定值

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

将'&&'放在'{'?此外,这些字段通过'$ NF'编号为'$ 1'; “$ 0”是整条线。根据显示的数据判断,“参考”和“标准”之间没有标签。 'FNR == NR'条件意味着文件被读取,保存且不再存在;以下术语从不执行,因为没有第二个文件要读取。你可以在'END'块中完成。目前还不清楚'你的意思是'和'$ 3'值是否匹配' - 他们需要匹配什么?你需要澄清你试图找到的东西。一旦要求得到充分描述,就不难做到。 –

+0

“$ 3”值匹配表示它们是相同的。每个“$ 3”值可能会重复多次,但通常只有一个“参考标准”的“$ 10”值。我试图在那些不符合标准的文件中找到那些......这就是'$ 3'值相同而$ 10'是'参考标准'的地方。谢谢 :)。 – Chris

+1

你必须更加精确。你的意思是两个不同的行在'$ 3'中具有相同的值?不管其他领域有什么?你想同时打印两行?如果在$ 3中有三行具有相同的值,您想要打印3行还是3行?在你的样本数据中,'$ 3'中的重复也会重复'$ 1'和'$ 2'(和$ 4')中的值 - 这很重要吗? –

回答

1

对于只有几千行,这大概是最容易处理的数据文件(我的是称为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 

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

+0

非常感谢,我一直在思考,但不知道如何实现它....感谢您的帮助和解释:) – Chris

相关问题