假设我有两个文件,文件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
答案 0 :(得分:1)
这将使用join
和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
单独执行此操作的方法,因此{ {1}}救援。
Awk代码非常简单。如果字段数(awk
变量)大于4,我们有一个连接线;在这种情况下,打印字段1,5,6和7.否则,打印整个原始行(因为它未连接)。
这将发出未修改的每个不匹配的行,以及每个匹配行的file2版本。
答案 1 :(得分:1)
使用sed:
join -a 1 in1 in2 | sed 's/^\([0-9]*\) [^ ]* [^ ]* [^ ]* /\1 /'