我有一个 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
这是解决方案。
- 创建文件
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
- 执行它:
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
- 如果您希望在输出中使用逗号作为分隔符,您可以更改:
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
- 选修的。如果你想包含
fileA.txt
标题(第一行)A)您可以简单地更改条件:FNR>=1
或b)简短地重写脚本:
#!/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
(我刚刚意识到通过复制你的示例,我用空格替换了制表符)
这标题和版本行可能是标题,因此需要进行一些后处理。