如何根据匹配的键字段用另一个文件中的行替换文本文件中的行?

时间:2012-05-31 06:09:39

标签: bash unix sed awk

input.txt中

1,Ram,Fail
2,John,Fail
3,Ron,Success

param.txt(新输入)

1,Sam,Success
2,John,Sucess

现在我想将input.txt中的整行替换为param.txt中的整行。 第一列将充当主键。

Output.txt的

1,Sam,Success
2,John,Sucess
3,Ron,Success

我试过

awk 'FNR==NR{a[$1]=$2 FS $3;next}{ print $0, a[$1]}' input.txt param.txt > Output.txt 

但它正在合并文件内容。

5 个答案:

答案 0 :(得分:5)

这可能适合你(GNU sed):

 sed 's|^\([^,]*,\).*|/^\1/c\\&|' param.txt | sed -f - input.txt

说明:

  • 使用第一个字段作为地址将param.txt转换为sed脚本,以更改input.txt中的行。 s|^\([^,]*,\).*|/^\1/c\\&|
  • 针对input.txt运行脚本。 sed -f - input.txt

答案 1 :(得分:3)

这可以通过拨打sort来完成:

sort -t, -k1,1n -us param.txt input.txt

在第一个以逗号分隔的字段上使用稳定的数字排序,并在param.txt之前列出input.txt,以便在删除重复项时首选正确的新行。

答案 2 :(得分:2)

您可以使用join(1)来完成这项工作:

$ join -t, -a1 -j1 Input.txt param.txt | sed -E 's/,.*?,.*?(,.*?,.*?)/\1/'
1,Sam,Success
2,John,Sucess
3,Ron,Success

sed as a pipe tail将Input.txt中的字段从替换行中删除。

仅当两个输入文件都按第一个字段排序时才会起作用。

答案 3 :(得分:2)

Pure awk并不是真正适合这项工作的工具。如果您必须仅使用awk,https://stackoverflow.com/a/5467806/1301972是您工作的良好起点。

但是,Unix提供了一些工具,可以帮助您为正在尝试的操作提供正确的输入。

$ join -a1 -t, <(sort -n input.txt) <(sort -n param.txt) |
     awk -F, 'NF > 3 {print $1 "," $4 "," $5; next}; {print}'

基本上,你在awk中输入一个文件,其中的行连接在input.txt的键上。然后awk可以解析出你想要正确显示的字段或重定向到输出文件。

答案 4 :(得分:1)

这应该适用于awk

awk -F"," 'NR==FNR{a[$1]=$0;next} ($1 in a){ print a[$1]; next}1' param.txt input.txt

测试:

$ cat input.txt 
1,Ram,Fail
2,John,Fail
3,Ron,Success
$ cat param.txt 
1,Sam,Success
2,John,Sucess
$ awk -F"," 'NR==FNR{a[$1]=$0;next} ($1 in a){ print a[$1]; next}1' param.txt input.txt 
1,Sam,Success
2,John,Sucess
3,Ron,Success