首页 > 解决方案 > 合并多个文件

问题描述

我尝试组合具有相同列数的几个文件(正好 10 个):

index lat lon value

这些文件有不同的行数(即index lat lon文件中缺少一些)

我想获得一个文件:

索引 lat lon value_of_file1 value_of_file2 value_of_file3 value_of_file4 value_of_file5 value_of_file6 value_of_file7 value_of_file8 value_of_file9 value_of_file10

问题是“索引纬度”在我的文件中的顺序不同。为了更清楚,这是我的输入(仅显示 2 个文件):

文件 1(仅显示几行,但实际文件中还有更多):

指数纬度值

50 80 12 50.25
50 80.5 12.5 80.25 
80 80 12 28.52
80 80.5 12.5 35.89

文件 2:

指数纬度值

80 80 12 38.52
80 80.5 12.5 38.25
30 28.5 52.5 12.35
30 27.5 55.5 18.52
50 80 12 28.52

所需的输出(仅显示前两行):

索引 lat lon value_of_file1 value_of_file2 value_of_file3 value_of_file4 value_of_file5 value_of_fine6 value_of_file7 value_of_file8 value_of_file9 value_of_file10

50 80 12 50.25 28.52 35.22 78.89 54.42 65.23 89.56 42.25 12.23 40.15
50 80.5 12.5 80.25 0 12.25 56.55 85.96 41.23 22.12 24.57 18.26 47.89

我怎么能用 awk 做到这一点?

标签: awk

解决方案


您可以通过创建一个不按数字索引而是通过前 3 列索引的数组来执行此操作。最简单的方法是,

awk '{key=$1 OFS $2 OFS $3}
     {a[key] = a[key] OFS $4}
     END { for (key in a) print key a[key] }' file1 file2 file3 ...

但是,如果您想要0.0在文件没有条目的地方,那么您必须跟踪哪些文件有,哪些文件没有。一种方法如下,

awk '(FNR==1){f++}
     {key=$1 OFS $2 OFS $3}
     { for(i=b[key]+1; i<f; ++i) a[key] = a[key] OFS "0.0"; b[key]=f }
     { a[key] = a[key] OFS $4 }
     END { for (key in a) {
              for(i=b[key]+1;i<=f; ++i) a[key] = a[key] OFS "0.0";
              print key a[key]
           }
     }' file1 file2 file3 ...

这是如何运作的:

  • 数组a跟踪由索引的值字符串key
  • 数组b跟踪已添加到的最后一个文件a,该数组用于添加缺失的零。因为默认情况下 any 的值b[key]0,我们修复了第一个文件中缺少的键。(假设key"40 50 60"只在第四个文件中第一次出现,需要修复0.0前三个文件的缺失值)
  • 该变量f跟踪我们开始处理的文件号。每次我们读取文件的第一条记录时它都会增加(FNR==1)
  • 每次添加条目时,我们首先检查添加的最后一个文件是什么,并用“0.0”填充缺失的位。
  • 最后,在我们打印值之前,我们首先检查最终文件中是否缺少值“0.0”。如果是这样,我们将它们添加到a[key].

推荐阅读