我有两个文件。 file_1.txt 看起来像这样:
R1 C1 C2 C3 C4 C5
R2 C1 C2 C3 C4 C5
R3 C1 C2 C3 C4 C5
R4 C1 C2 C3 C4 C5
R5 C1 C2 C3 C4 C5
R6 C1 C2 C3 C4 C5
R7 C1 C2 C3 C4 C5
R8 C1 C2 C3 C4 C5
R9 C1 C2 C3 C4 C5
R10 C1 C2 C3 C4 C5
file_2.txt 看起来像这样:
R4 C4 C5
R6 C4 C5
R7 C4 C5
R9 C4 C5
我想将 file_1.txt 中的 C4 和 C5 值替换为 file_2.txt 中对应的值,同时保持 file_1.txt 中的 C1、C2 和 C3 值不变。
因此生成的 file_3.txt 应如下所示:
R1 C1 C2 C3 C4 C5
R2 C1 C2 C3 C4 C5
R3 C1 C2 C3 C4 C5
R4 C1 C2 C3 C4_new C5_new
R5 C1 C2 C3 C4 C5
R6 C1 C2 C3 C4_new C5_new
R7 C1 C2 C3 C4_new C5_new
R8 C1 C2 C3 C4 C5
R9 C1 C2 C3 C4_new C5_new
R10 C1 C2 C3 C4 C5
所有值都是数字。 file_1.txt 和 file_2.txt 中的第一列是关键字段,按数字升序排序。
这是一个人加入就可以做的事情吗?
答案1
这个问题的典型应用是awk
awk 'NR == FNR{a1[$1]=$2; a2[$1]=$3; next};
$1 in a1{$5=a1[$1]; $6=a2[$1]};{print}' file_2.txt file_1.txt
您可能必须将输出字段分隔符显式设置为制表符,在这种情况下
awk -v OFS='\t' 'NR == FNR{a1[$1]=$2; a2[$1]=$3; next};
$1 in a1{$5=a1[$1]; $6=a2[$1]};{print}' file_2.txt file_1.txt
答案2
这并不能解决您的问题,而是向您展示为什么join
名义上听起来它应该在这种特定情况下起作用,但事实并非如此。我花了相当多的时间试图join
在这个网站上解决与您类似的问题,标题为:使用唯一标识符连接两个文件。
第一种方法
解决您的问题的方法join
如下:
$ join -a1 -1 1 -2 1 -o 1.1 1.2 1.3 1.4 2.2 2.3 <(sort file_1.txt) <(sort file_2.txt)
R10 C1 C2 C3
R1 C1 C2 C3
R2 C1 C2 C3
R3 C1 C2 C3
R4 C1 C2 C3 C4_new C5_new
R5 C1 C2 C3
R6 C1 C2 C3 C4_new C5_new
R7 C1 C2 C3 C4_new C5_new
R8 C1 C2 C3
R9 C1 C2 C3 C4_new C5_new
正如您所看到的,join
需要将文件放入排序的形式,因此对于初学者来说,如果文件的原始顺序很重要,则此选项可能会造成问题。
此外,无法join
根据列的值、存在值或缺少值来判断从一个文件或另一个文件有条件地打印列的值。
第二种方法
另一种方法join
可能是这样的:
$ join -a1 -1 1 -2 1 <(sort file_1.txt) <(sort file_2.txt)
R10 C1 C2 C3 C4 C5
R1 C1 C2 C3 C4 C5
R2 C1 C2 C3 C4 C5
R3 C1 C2 C3 C4 C5
R4 C1 C2 C3 C4 C5 C4_new C5_new
R5 C1 C2 C3 C4 C5
R6 C1 C2 C3 C4 C5 C4_new C5_new
R7 C1 C2 C3 C4 C5 C4_new C5_new
R8 C1 C2 C3 C4 C5
R9 C1 C2 C3 C4 C5 C4_new C5_new
它再次接近您想要的,但不允许您使用任何条件逻辑从一个文件或另一个文件打印一列。
第三种方法
这个可行,但我们必须分解并获得一些外部帮助,以awk
省略当其对应项存在于 中时会移位的尾随列file_2.txt
。
$ join -a1 -1 1 -2 1 -o 1.1 1.2 1.3 1.4 2.2 2.3 1.5 1.6 1.7 <(sort file_1.txt) <(sort file_2.txt) | awk '{$7=$8=""}1'
R10 C1 C2 C3 C4 C5
R1 C1 C2 C3 C4 C5
R2 C1 C2 C3 C4 C5
R3 C1 C2 C3 C4 C5
R4 C1 C2 C3 C4_new C5_new
R5 C1 C2 C3 C4 C5
R6 C1 C2 C3 C4_new C5_new
R7 C1 C2 C3 C4_new C5_new
R8 C1 C2 C3 C4 C5
R9 C1 C2 C3 C4_new C5_new
使用刚刚加入吗?
Join 的市场范围非常狭窄,它可以成为一个有用的工具。对于替换类型的问题(您的问题更符合该问题),诸如awk
、perl
、 或 之类的工具sed
会更适合。