awk - 合并多个文件
问题描述
我尝试组合具有相同列数的几个文件(正好 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 做到这一点?
解决方案
您可以通过创建一个不按数字索引而是通过前 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]
.
推荐阅读
- django - 如何让 django 模板识别多域比较?
- azure - 自动触发安全中心剧本
- azure - 无法在 Azure Functions V2 中注册 CosmosDB 绑定扩展
- r - 如何删除空单元格并减少列
- java - 如何制作自定义视图的隐藏和显示动画
- ios - Objective-c 每 23 个字符换行而不断字
- javascript - Algolia 搜索结果覆盖了 css 格式
- python - 如何在仅对应于某些日期的字符串中返回分号后的数字?
- cherrypy - 为什么内容类型为 application/x-www-form-urlencoded 时请求正文为空白?
- jquery - Ajax:获取 DropdownList 的 ID 值