如何解释和优化awk数组以匹配和修改两个文件的公共列

问题描述 投票:0回答:1

在尝试了一整天以获得更多awk和数组之后,我的代码现在大致(我认为)我希望的内容:基于公共列匹配两个文件,然后从文件1到文件2添加另一列。以前曾被问及我尝试了很多不同的版本,但它现在的工作更巧合,我有这样的印象。

人们已经试图在相关案件中帮助我

how to use awk to add specific values to a column based on numeric rangesprint output of user-defined function in awk gives unexpected token error等)

但不同的解决方案在我脑海中相撞,现在有一团糟。

虽然我的代码有点工作,但它现在打印出匹配的行两次(?)并且它也很慢。我确信有很多优化,你能给我一些关于我实际在做什么以及如何改进它的提示吗?现在这只适用于一对文件,我有大约一对这样的文件。

contig_lengths_cut.txt(300.000行):

 k141_157024 1 1011
k141_158290 1 462
k141_158291 1 1648
k141_158292 1 329
k141_158293 1 534
k141_158294 1 497
k141_158295 1 418482
k141_186288 1 324
k141_186289 1 340
k141_186290 1 390
k141_186291 1 206156
k141_186292 1 491
k141_186293 1 759
k141_186294 1 4885
k141_186295 1 2736
k141_185742 1 377
k141_185743 1 6775
k141_185744 1 301

gene_length.txt(50到300行)

k141_185743 1184 gene=phnM_10
k141_186291 1247 gene=phnM_11
k141_186291 1226 gene=phnM_12
k141_157024 350 gene=phnM_9
k141_158295 1160 gene=phnM_10
k141_158295 1145 gene=phnM_11
k141_247338 410 gene=phnM_1

我的代码:

awk 'NR==FNR { 
            contig[$1]=$3; next}; 
                {for (k in contig) 
                    if ($3 ~ contig[k]) print $0, contig[$1] }' 
contig_lengths_cut.txt gene_length.txt

当前输出是:

#with the updated data it is not working at all, if I add more lines to the #sample data, it works again...something is going spectacularly wrong

我想要的输出是:

k141_185743 1184 gene=phnM_10 6775
k141_186291 1247 gene=phnM_11 206156
k141_186291 1226 gene=phnM_12 206156
k141_157024 350 gene=phnM_9 1011
k141_158295 1160 gene=phnM_10 418482
k141_158295 1145 gene=phnM_11 418482    
#k141_247338 410 gene=phnM_1 #no match, don't print

我假设contig[$1]=$3意味着(仅针对第一个文件)第一列文件用作索引而第三列用作赋值?

对于数组contig中的所有这些元素,第二个文件中的第三列用于匹配?在我看来,这不会太有意义。但是如果我使用第一列,我会获得100个相同的条目,而如图所示,我得到了所需的行数。

最后我打印第二个文件的整行+数组的索引列,它代表第一个文件的第三列,对吗?

对不起,请帮助我理解我在这里做的事情所以我不必再频繁地问这个了;-)

arrays bash awk
1个回答
1
投票

您的输入样本没有提供足够的数据来测试和匹配您的输出。但是,我认为我得到了你的问题。您正在寻找值的正则表达式匹配,而不是键上的完全匹配。如果您将脚本更改为

awk 'NR==FNR {contig[$1]=$3; next}                    
     $1 in contig {print $0, contig[$1]}' contig_lengths_cut.txt gene_length.txt

应该工作正常。但是,由于缺乏可测试数据,因此未进行测试。

就速度而言,如果您的文件没有排序,这将是最快的。您可以将file1拆分为块,对file2执行所有file1块的并行运行并合并结果。

如果要调试原始代码,请将contig[k]添加到print语句中。

© www.soinside.com 2019 - 2024. All rights reserved.