繁体   English   中英

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

[英]How can I replace lines in a text file with lines from another file based on matching key fields?

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 

但它正在合并文件内容。

这可能适合你(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

这可以用一个调用完成sort

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

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

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

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

sed作为管道尾部从Input.txt中删除替换行中的字段。

仅当两个输入文件都按第一个字段排序时,这才有效。

纯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可以解析出你想要正确显示的字段或重定向到输出文件。

这应该在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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM