bash-使用 2 个公共列合并 2 个文件并添加第 3 列的值

bash-使用 2 个公共列合并 2 个文件并添加第 3 列的值

我是 bash shell 和所有 unix 命令的新手。所以我希望我的问题不是太愚蠢,我在之前的问题中找不到任何可以帮助我解决问题的东西。

我创建了一个如下所示的文件:

apple:::NN \t garden:::NN \t 5
garden:::NN \t great:::Adj \t 1
nice:::Adj \t a:::DT \t 2
etc

现在我有另一个文件:

apple:::NN \t garden:::NN \t 15
house:::NN \t nice:::Adj \t 1
garden:::NN \t great:::Adj \t 5
etc

我需要合并这些文件,因此合并后的输出文件将如下所示:

apple:::NN \t garden:::NN \t 20
garden:::NN \t great:::Adj \t 6
nice:::Adj \t a:::DT \t 2
house:::NN \t nice:::Adj \t 1

问题是两个文件中的行不相同,所以我无法逐行遍历文件。当然,我可以拆分行,但是如果两个文件中的第 1 列和第 2 列相同,我必须将第 1 列和第 2 列视为一个单位,才能将数字相加。在 1 个文件中找到的行必须按原样进入输出文件。

我可以使用“awk”或“grep”手动完成此操作,但是是否可以在循环中执行此操作?如果有人能提示如何解决“line”问题,那将对我有很大帮助!

我能找到的最接近的解决方案如下使用公共列合并文件但是,我无法获得使用 2 列加上第 3 列的值的连接命令。

我非常感谢您的帮助!

答案1

这类问题的“经典”解决方案是使用 awk 中的关联数组:

$ awk 'BEGIN{FS="\t"; OFS=FS} {a[$1 FS $2] += $3;} END {for (i in a) print i, a[i]}' file1 file2
nice:::Adj      a:::DT  2
house:::NN      nice:::Adj      1
apple:::NN      garden:::NN     20
garden:::NN     great:::Adj     6

(请注意,输出顺序无法保证)。可以perl使用哈希来实现类似的算法。

您可能希望尝试的一个较新的工具是GNU 数据聚合允许按字段分组并对结果进行各种数学运算,例如

$ cat file1 file2 | datamash -s groupby 1,2 sum 3 
apple:::NN      garden:::NN     20
garden:::NN     great:::Adj     6
house:::NN      nice:::Adj      1
nice:::Adj      a:::DT  2

相关内容