根据第一列的匹配值替换文件第二列中的值

根据第一列的匹配值替换文件第二列中的值

我有一个 fileA.txt ,如下所示:

title              trial_exp  values
Version            1.0
Blank1                        0.010
Blank2                        0.200
Blank3                        0.100
Test_field_Asia               1.500
Test_field_Europe             0.900
Test_field_America            2.000

然后我有一个 fileB.txt ,如下所示:

Test_field_Asia     Thailand
Test_field_Europe   UK
Test_field_America  Mexico

我想要将 fileA 第 1 列中的所有名称与 fileB 第 1 列中的名称进行匹配,并在找到匹配项时替换第 2 列中的值:

期望的输出:

title               trial_exp   values
Version             1.0
Blank1                          0.010
Blank2                          0.200
Blank3                          0.100
Test_field_Asia     Thailand    1.500
Test_field_Europe   UK          0.900
Test_field_America  Mexico      2.000

我尝试了以下代码:

awk 'NR==FNR{rec[$1]=$2;next}{temp=$1} temp in rec{$2=rec[temp]}1' fileA.txt fileB.txt

但是,替换尚未完成,我得到了原始 fileA.txt 打印的 ou

有人可以向我解释这段代码有什么问题或建议替代解决方案吗?

答案1

这是解决方案

  1. 创建文件myscript.sh
#!/bin/bash
awk 'BEGIN{FS=",";OFS="\t"}
    FNR==NR{myfile2[$1]=$2; next}
    FNR>1{if(myfile2[$1]){print $1, myfile2[$1], $3,NR}else{print $1,$2,$3}}
' fileB.txt fileA.txt
  1. 执行它:
chmod +x myscript.sh
./myscript.sh

你会得到这样的输出:

Version 1.0 
Blank1      0.010
Blank2      0.200
Blank3      0.100
Test_field_Asia Thailand    1.500   9
Test_field_Europe   UK  0.900   10
Test_field_America  Mexico  2.000   11
  1. 如果您希望在输出中使用逗号作为分隔符,您可以更改:OFS="," 您将得到以下输出:
Version,1.0,
Blank1,,0.010
Blank2,,0.200
Blank3,,0.100
Test_field_Asia,Thailand,1.500,9
Test_field_Europe,UK,0.900,10
Test_field_America,Mexico,2.000,11
  1. 选修的。如果你想包含fileA.txt标题(第一行)A)您可以简单地更改条件:FNR>=1b)简短地重写脚本:
#!/bin/bash
awk 'BEGIN{FS=",";OFS="\t"}
    FNR==NR{myfile2[$1]=$2; next}
    myfile2[$1]{print $1, myfile2[$1], $3; next;}{print $1,$2,$3}
' fileB.txt fileA.txt

最后,如果您想要详细的示例,请阅读: https://www.baeldung.com/linux/awk-multiple-input-files

答案2

您想要的本质上是数据库连接。有一个命令可以做到这一点,恰当地命名为join.问题是它需要排序输入。如果行顺序不相关,您可以执行以下操作:

join -a1 <(sort fileA.txt) <(sort fileB.txt)

-a1 选项打印无法合并的行。两个 <(...) 构造生成包含 sort 命令输出的临时文件。使用您的示例,结果是

Blank1 0.010
Blank2 0.200
Blank3 0.100
Test_field_America 2.000 Mexico
Test_field_Asia 1.500 Thailand
Test_field_Europe 0.900 UK
title trial_exp values
Version 1.0

(我刚刚意识到通过复制你的示例,我用空格替换了制表符)

标题版本行可能是标题,因此需要进行一些后处理。

相关内容