我想像这样合并两个表
表格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
脚本最后一行的是awk
awk 的惯用简写形式{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