0

假设我有两个文件,文件 1 包含原始数据,而最近创建的文件 2 更新了一些需要替换到文件 1 中的数据的值。

下面是文件 1 的格式示例,其中包含 10000 行数据,如下所示:

1000001 aaaaaaa aaaaaaa 123
1000002 aaaaaab aaaaaab 123
.
.
.
1000503 xxxxxxa xxxxxxa 123
.
.
.
1010000 zzzzzzl zzzzzzl 123

文件 2 包含 1054 行更新值,其格式与文件 1 相同,但其中许多不是连续的。例如,文件 2 中的第 1000503 行将如下所示:

1000503 xxxxxxb xxxxxxb 245
4

2 回答 2

1

这将使用joinand来执行此操作awk,假设文件按密钥顺序排列:

join -a1 -j1 file1 file2 \
    | awk '{ if (NF > 4) print $1, $5, $6, $7; else print $0 }'

这在两遍中完成了这项工作。

合并文件

首先,join获取两个具有公共列(在本例中为前导数字列)的文本文件,然后像数据库连接一样“连接”它们。默认情况下,它会打印在两个文件中都出现密钥的所有行。 -j1告诉它加入第一个字段。-a1告诉它打印文件 1 中的所有行,即使它们在文件 2 中没有相应的行。

join确实有两个文件都按键排序的限制。

这会生成文件 1 的副本,其中还包括文件 2 中的匹配行,如下所示:

1000001 aaaaaaa aaaaaaa 123
1000002 aaaaaab aaaaaab 123
.
.
.
1000503 xxxxxxa xxxxxxa 123 xxxxxxb xxxxxxb 245
.
.
.
1010000 zzzzzzl zzzzzzl 123

拆分字段

我们现在有一个问题:匹配的行包含来自两个文件的数据。但是,这不是我们想要的:我们希望它替换文件 1 中的数据。我看不出有一种方法可以join自行完成,所以awk来救援。

awk 代码非常简单。如果字段(NF变量)的数量大于 4,我们有一条连接线;在这种情况下,打印字段 1、5、6 和 7。否则,打印整个原始行(因为它是未连接的)。

这将发出未修改的每个不匹配行,以及每个匹配行的 file2 版本。

于 2013-05-05T23:23:59.887 回答
1

使用 sed:

join -a 1 in1 in2 | sed 's/^\([0-9]*\) [^ ]* [^ ]* [^ ]* /\1 /'
于 2013-05-06T00:04:16.317 回答