2016-08-23 74 views
0

我需要将一个文件中的单个列条目与第二个文件中的列条目匹配,贝壳)。我使用的awk命令只匹配列表的第一个单词,并且不扫描列字段中的整个列表。将一个文件中的单列条目匹配到第二个文件中的列条目,该列条目由一个列表组成

文件1是这样的:

chr1:725751 LOC100288069   
rs3131980 LOC100288069   
rs28830877 LINC01128  
rs28873693 LINC01128  
rs34221207 ATP4A  

文件2如下所示:

Annotation Total Genes With Ann Your Genes With Ann) Your Genes No Ann) Genome With Ann) Genome No Ann) ln 
1 path hsa00190  Oxidative phosphorylation 55 55 1861 75 1139 5.9 9.64 0 0 ATP12A ATP4A ATP5A1 ATP5E ATP5F1 ATP5G1 ATP5G2 ATP5G3 ATP5J ATP5O ATP6V0A1 ATP6V0A4 ATP6V0D2 ATP6V1A ATP6V1C1 ATP6V1C2 ATP6V1D ATP6V1E1 ATP6V1E2 ATP6V1G3 ATP6V1H COX10 COX17 COX4I1 COX4I2 COX5A COX6B1 COX6C COX7A1 COX7A2 COX7A2L COX7C COX8A NDUFA5 NDUFA9 NDUFB3 NDUFB4 NDUFB5 NDUFB6 NDUFS1 NDUFS3 NDUFS4 NDUFS5 NDUFS6 NDUFS8 NDUFV1 NDUFV3 PP PPA2 SDHA SDHD TCIRG1 UQCRC2 UQCRFS1 UQCRH 

预期输出:

rs34221207 ATP4A hsa00190 

(请原谅的格式 - 所有列制表符分隔,直到基因名称列14美元,称为Genome ...)

我的命令是这样的:

awk 'NR==FNR{a[$14]=$3; next}a[$2]{print $0 "\t" a[$2]}' file2 file 1 

所有帮助将非常感激!

+0

这两个文件有匹配吗? –

+0

基于这两个文件的预期输出是什么? – oliv

+0

我编辑了你的'file2',使它包含字符串'LOC100288069'作为第14个字段,并且我运行了'awk'代码......它按预期工作。很明显,使用'file1'和'file2'的例子,你的'awk'代码不能打印任何东西。 – Jdamian

回答

1

你需要处理的其他命令文件,并遍历列表:

awk 'NR==FNR{a[$2]=$1; next} {for(i=15;i<=NF;++i)if(a[$i]){print a[$i] "\t" $i "\t" $3}}' file1 file2 

说明:

NR是一个全球性的“备案号”反了awk递增读取每一行每个文件。 FNR是每个文件的“记录号”,awk在每个文件的第一行重置为1。因此NR==FNR条件对于第一个文件中的行是真实的,对于后续文件中的行是false。这是一个awk习惯用于挑选第一个文件信息。在这种情况下,a[$2]=$1存储由第二个字段文本键入的第一个字段文本。 next告诉awk在当前行停止短路并读取并继续正常处理下一行。在这样的第一个动作子句末尾的next在功能上与其余代码中的ELSE条件相同,如果awk具有这样的语法(它没有):NR==FNR{a[$2]=$1} ELSE {for...NR==FNR{a[$2]=$1}NR!=FNR{for...更清晰,只有稍微省时的效率。

现在到第二个动作条款。前面没有任何条件意味着awk会为没有被前面的next短路的每一行执行它,也就是说,只有在这种情况下,第一个文件2以外的文件中的所有行。你的file2有一个从字段#15开始并延伸到最后一个字段的潜在密钥列表。最后一个字段编号的awk内置变量是NF(字段数)。 for循环是非常明显的,然后只循环这些字段数字。对于i中的每一个数字,我们想知道该字段$i中的文本是否是第一个文件中的已知密钥 - 设置了a[$i],即,计算结果为非空(非错误)字符串。如果是这样,那么我们在a[$i]中有我们的file1第一个字段,我们的匹配file1第二个字段在$i,我们的file2字段在$3(当前file2第三个字段的文本)中。将它们打印为制表符分隔。 next这里是一个只有效率的度量,一旦我们找到匹配就停止对file2记录的所有处理。如果您的file2密钥列表可能包含重复项,并且您希望重复输出行(如果这样的重复项匹配),那么您必须删除最后一个next

事实上,现在我再次看,你可能确实想找到任何多个匹配,即使在非重复,所以我已经从代码中删除第二个next

+0

note'print a“\ t”b'等可以用awk -v OFS =“,”'{print a,b}'来表示。也就是说,使用'print'设置OFS会更好。 – fedorqui

+1

请注意接下来是在里面。也许休息会更直观。 –

+0

谢谢!我不熟悉编码,你会介意解释你的命令吗? – Hannah6746576

相关问题