根据公共的两列连接两个表,如果不匹配则添加 NA 或空值

根据公共的两列连接两个表,如果不匹配则添加 NA 或空值

我想像这样合并两个表

表格1

Chr1 5
Chr1 10
Chr1 20
Chr2 10
Chr2 30

表_2

Chr1 10 value value2
Chr1 20 value value2
Chr2 30 value value2

所需输出

Chr1 5
Chr1 10 value value2
Chr1 20 value value2
Chr2 10
Chr2 30 value value2

我在 awk 中找到了用于合并表的脚本,仅保留与两个表中的两列匹配的行。但在这里,我想要 Table_1 的所有行,但如果它们匹配,则添加 Table_2 的值。您能告诉我如何实现这一目标吗?

答案1

$ awk '{ key = $1 FS $2 };
       NR == FNR { t[key] = $0; next };
       key in t { print t[key]; next };
       1' table2.txt table1.txt
Chr1 5
Chr1 10 value value2
Chr1 20 value value2
Chr2 10
Chr2 30 value value2
  • 在读取的每个输入行(对于读取的两个文件)中,变量key设置为前两个字段($1$2),并在它们之间使用字段分隔符(FS)。 FS使用它是因为它是唯一保证不在任一字段中的字符),因此也是唯一保证生成唯一键的字符。该键用作名为 的关联数组的索引t

  • 当它读到时table2.txt时(必须被列为命令行上的第一个文件名 arg),每个输入行都存储在数组的一个元素中t

    如果table2.txt包含重复的条目 - 即具有相同前两个字段的多行 - 它只会记住最后的一个看到的。如果您希望它记住所有此类重复项(按照出现的顺序),请将 awk 脚本的第二行更改为:

     NR == FNR { if (key in t) { t[key] = t[key] "\n" $0 } else { t[key] = $0 }; next };
    
  • 当它完成读取第一个文件时,它读入table1.txt(第二个文件名arg)并打印数组中的相应条目table2(如果存在),否则打印当前行。

  • 1脚本最后一行的是awkawk 的惯用简写形式{print}- 值1计算为 true,当某些值计算为 true 时,默认操作是打印当前行。

注意:如果table2.txt很大,这将使用大量 RAM。对于任何具有千兆字节 RAM 的现代系统来说,这不太可能成为问题。

答案2

$ awk '{k=$1 FS $2} NR==FNR{map[k]=$0; next} {print (k in map ? map[k] : $0)}' table2 table1
Chr1 5
Chr1 10 value value2
Chr1 20 value value2
Chr2 10
Chr2 30 value value2

相关内容