【问题标题】:awk comparing two filesawk 比较两个文件
【发布时间】:2018-03-04 03:54:55
【问题描述】:

我需要一个 awk 脚本来比较两个文件的第一列以制表符分隔,每次匹配时我需要打印第二个文件,否则我需要第一个文件的所有行

file1.txt

denovo0  bacteria   0.99  
denovo1  bacteria   0.98  
denovo2  bacteria;Firmicutes;clostridium    0.99  
denovo3  bacteria;Firmicutes;bacillus   0.98  

file2.txt

denovo0  bacteria;Gammaproteobacteria;pseudomonas   0.99  
denovo1  bacteria;Alphaproteobacteria;Rhizobium     0.98

desired_output.txt

denovo0  bacteria;Gammaproteobacteria;pseudomonas  0.99  
denovo1  bacteria;Alphaproteobacteria;Rhizobium  0.98  
denovo2  bacteria;Firmicutes;clostridium    0.99  
denovo3  bacteria;Firmicutes;bacillus   0.98  

【问题讨论】:

  • 代码标签是为了更好地理解问题/答案,请再次添加它们以便更好地查看您的帖子,还请通过示例更清楚地说明您的问题。

标签: join awk compare


【解决方案1】:

这个awk 应该适合你:

awk -v OFS='\t' 'NR==FNR{a[$1]=$2; next} $1 in a{$2=a[$1]} 1' file2 file1

denovo0 |bacteria;Gammaproteobacteria;pseudomonas| 0.99
denovo1 |bacteria;Alphaproteobacteria;Rhizobium| 0.98
denovo2 |bacteria;Firmicutes;clostridium|   0.99
denovo3 |bacteria;Firmicutes;bacillus|  0.98

如果您想要表格输出,请将其通过管道传输到 column -t

awk -v OFS='\t' 'NR==FNR{a[$1]=$2; next} $1 in a{$2=a[$1]} 1' file2 file1 | column -t

denovo0  |bacteria;Gammaproteobacteria;pseudomonas|  0.99
denovo1  |bacteria;Alphaproteobacteria;Rhizobium|    0.98
denovo2  |bacteria;Firmicutes;clostridium|           0.99
denovo3  |bacteria;Firmicutes;bacillus|              0.98

【讨论】:

  • 这是因为 OP 在我回答后更改了示例数据。我现在已经更新了我的答案。
  • 感谢@anubhava !!!它工作得很好!实际上第一个有效,因为原始文件已经用制表符分隔
  • 对不起,anubhava,仔细查看输出文件,我注意到由于某些原因,一些替换的行丢失了格式。我不明白为什么,这些行都是空格分隔而不是制表符分隔
  • 我在awk 解决方案中添加了-v OFS='\t',以便输出仅以制表符分隔。另请注意,您没有在任何地方提到您的输入有问题中显示的制表符而不是空格。
【解决方案2】:
awk 'NR==FNR{a[$1]=$1;b[$1]=$0;next} $1==a[$1]{print $0 ;delete b[$1]}END{for (i in b ) print b[i]}'  file1 file2

说明

NR==FNR{a[$1]=$1;b[$1]=$0;next} :读取 file1 并分配数组 a 与第一列和 b 与行作为值。

$1==a[$1]{print $0 ;delete b[$1]} :检查a 中的值是否与file2 的第一列匹配,如果是,则打印file2 的行并从数组b 中删除该行。

END{for (i in b ) print b[i]} : 打印数组 b 中的剩余项目,即 file1 的剩余行

【讨论】:

  • 请解释您的代码是如何工作的,最好是一些示例输入以及您的代码使用该输入产生的输出。
  • 让我知道您具体哪一部分不明白?输入输出与OP完全相同。
  • 解释您的代码的作用并展示它的作用,如果有更多问题,我会告诉您。如果一切顺利,您的答案将在公共领域保存数十年。立即记录。不要等 17 年后有人问你解释 :)
  • NR==FNR{a[$1]=$1;b[$1]=$0;next} 读取 file1 并分配数组 a 与第一列和 b 与行作为值。 $1==a[$1]{print $0 ;delete b[$1]} 检查 a 中的值是否与 file2 的第一列匹配,如果是,则打印 file2 的行并从数组 b 中删除该行。 END{for (i in b ) print b[i]} 打印数组 b 中的剩余项目,即 file1 的剩余行。
  • 使用此信息编辑您的答案。没有人会阅读所有这些未格式化的 cmets :)。
猜你喜欢
  • 2012-09-05
  • 2017-01-31
  • 2017-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-25
相关资源
最近更新 更多