将一个文件中的列中的数据替换为另一个文件中的行中的数据

将一个文件中的列中的数据替换为另一个文件中的行中的数据

我是 Linux 环境的新手,我需要编写一个脚本来处理一些数据。

我有一个如下所示的文件:

文件A:

1    X   1    1.0
2    X   1    1.0
3    X   1    1.0
4    Y   2    1.0
5    Y   2    1.0
6    Z   3    1.0

另一个文件如下所示:

文件B:

1 0.5
2 0.3
3 0.2

我需要将文件 A 第 4 列中的数字替换为文件 B 第 2 列中出现的数字,但它必须将文件 A 第 3 列中的数字与文件 A 第 1 列中的数字相匹配文件B

所需的输出是:

1    X   1    0.5
2    X   1    0.5
3    X   1    0.5
4    Y   2    0.3
5    Y   2    0.3
6    Z   3    0.2

答案1

如果您无法对文件进行排序,请使用 Awk,它(如join)是为处理分隔数据而设计的。

在这种情况下,首先传递第二个文件,构建一个查找表,然后在传递第一个文件时使用查找表修改该文件的每一行。

$ cat file2
1 0.5
2 0.3
3 0.2
$ cat file1
1    X   1    1.0
2    X   1    1.0
3    X   1    1.0
4    Y   2    1.0
5    Y   2    1.0
6    Z   3    1.0
$ awk 'NR==FNR {a[$1] = $2; next} {$4 = a[$3]} 1' file2 file1
1 X 1 0.5
2 X 1 0.5
3 X 1 0.5
4 Y 2 0.3
5 Y 2 0.3
6 Z 3 0.2
$

答案2

使用join

join -1 3 -o 1.1,1.2,0,2.2 file1 file2

使用提供的文件输出:

$ cat file1
1    X   1    1.0
2    X   1    1.0
3    X   1    1.0
4    Y   2    1.0
5    Y   2    1.0
6    Z   3    1.0
$ cat file2
1 0.5
2 0.3
3 0.2
$ join -1 3 -o 1.1,1.2,0,2.2 file1 file2
1 X 1 0.5
2 X 1 0.5
3 X 1 0.5
4 Y 2 0.3
5 Y 2 0.3
6 Z 3 0.2
$ 

请注意,两个输入文件都必须排序(针对您希望将它们加入的列)。那是词典编法sort -n需要排序,而不是数字,因此如果有超过十个项目,请确保对文件进行适当的排序。 (加入后可以再次度假村。)

答案3

如果您无法对输入进行排序,那么join将无法工作,但您可以使用sed它。这个想法是使用sed一次将 fileB 转换为脚本,然后将该脚本反馈回以sed转换 fileA。

因此,在一行中,使用标准 POSIX shell 命令替换:

sed -e "$(sed 's:^\([0-9]*\) \(.*\)$:s/\1  *[^ ]*$/\1    \2/:' file2)" file1

相关内容