【问题标题】:Match up to on one column of file with another file and replace different column using bash将文件的一列与另一文件匹配并使用 bash 替换不同的列
【发布时间】:2018-02-04 18:40:00
【问题描述】:

我对此有点菜鸟,所以如果我不够清楚,请原谅我的无知。我有两个文件。 File1 如下所示。

file1

AA--:Aa-to-Bb:VGG sometext 1223344 10000 sometext
AB--:Aa-to-Bb:VGG sometext 1223344 12000 sometext
CC--:Dd-to-Ee:VGG sometext 1223344 44000 sometext
AA--:Zz-to-Yy:VGG sometext 1223344 51000 sometext
DD--:Aa-to-Dd:VGG sometext 1223344 36000 sometext

File2 看起来相似,但第 1 列和第 4 列存在差异。

file2

CC--:Dd-to-Ee:VGG6645 sometext 1223344 3000 sometext
AA--:Zz-to-Yy:VGG2244 sometext 1223344 1000 sometext
AA--:Aa-to-Bb:VGG12345 sometext 1223344 12200 sometext
AB--:Aa-to-Bb:VGG76523 sometext 1223344 33300 sometext
EE--:Dd-to-Ee:VGG45123 sometext 1223344 76500 sometext
DD--:Aa-to-Dd:VGG3486 sometext 1223344 400 sometext
AA--:Dd-to-Ee:VGG4512 sometext 1223344 22300 sometext
AA--:Zz-to-Dd:VGG98765 sometext 1223344 7000 sometext
CC--:Dd-to-Zz:VGG43576 sometext 1223344 900 sometext
FF--:Zz-to-Yy:VGG5645 sometext 1223344 91200 sometext
CC--:Zz-to-Ee:VGG23456 sometext 1223344 3400 sometext
AA--:Ff-to-Yy:VGG1111 sometext 1223344 51000 sometext

我正在尝试通过 bash 脚本进行一些自动处理。其中一项任务是比较两个文件。如果 file1 第 1 列中的条目与 file2 第 1 列中的条目匹配,直到并包括“VGG”,则 file1 中第 4 列的值将替换 file2 中第 4 列的值。

new file2

CC--:Dd-to-Ee:VGG6645 sometext 1223344 44000 sometext
AA--:Zz-to-Yy:VGG2244 sometext 1223344 51000 sometext
AA--:Aa-to-Bb:VGG12345 sometext 1223344 10000 sometext
AB--:Aa-to-Bb:VGG76523 sometext 1223344 12000 sometext
EE--:Dd-to-Ee:VGG45123 sometext 1223344 76500 sometext
DD--:Aa-to-Dd:VGG3486 sometext 1223344 36000 sometext
AA--:Dd-to-Ee:VGG4512 sometext 1223344 22300 sometext
AA--:Zz-to-Dd:VGG98765 sometext 1223344 7000 sometext
CC--:Dd-to-Zz:VGG43576 sometext 1223344 900 sometext
FF--:Zz-to-Yy:VGG5645 sometext 1223344 91200 sometext
CC--:Zz-to-Ee:VGG23456 sometext 1223344 3400 sometext
AA--:Ff-to-Yy:VGG1111 sometext 1223344 51000 sometext

我尝试过使用各种 awk 和 sed 命令,以及 grep、sort 和其他命令,但我无法获得我想要的结果。您的任何帮助或建议将不胜感激。

【问题讨论】:

  • 下一次,也放一些代码,而不仅仅是你的要求。作为初学者并不能保证您不付出一些努力来解决问题。
  • 列是如何定义的?行的顺序是否重要,是否需要保留?想到了“加入”命令,但需要排序输入。

标签: linux bash awk sed


【解决方案1】:

awk 下方可能有帮助

$ awk 'NR==FNR{rec[$1]=$4;next}{temp=$1;sub(/VGG[0-9]+$/,"VGG",temp)} temp in rec{$4=rec[temp]}1' file1 file2

输出

CC--:Dd-to-Ee:VGG6645 sometext 1223344 44000 sometext
AA--:Zz-to-Yy:VGG2244 sometext 1223344 51000 sometext
AA--:Aa-to-Bb:VGG12345 sometext 1223344 10000 sometext
AB--:Aa-to-Bb:VGG76523 sometext 1223344 12000 sometext
EE--:Dd-to-Ee:VGG45123 sometext 1223344 76500 sometext
DD--:Aa-to-Dd:VGG3486 sometext 1223344 36000 sometext
AA--:Dd-to-Ee:VGG4512 sometext 1223344 22300 sometext
AA--:Zz-to-Dd:VGG98765 sometext 1223344 7000 sometext
CC--:Dd-to-Zz:VGG43576 sometext 1223344 900 sometext
FF--:Zz-to-Yy:VGG5645 sometext 1223344 91200 sometext
CC--:Zz-to-Ee:VGG23456 sometext 1223344 3400 sometext
AA--:Ff-to-Yy:VGG1111 sometext 1223344 51000 sometext

如果需要重写file2

$ awk 'NR==FNR{rec[$1]=$4;next}
      {temp=$1;sub(/VGG[0-9]+$/,"VGG",temp)}
      temp in rec{$4=rec[temp]}1' file1 file2 >filetmp && mv filetmp file2

【讨论】:

  • 谢谢!!这非常有效。很抱歉没有在我的帖子中添加任何代码。我尝试了很多东西,我不确定要发布什么。开始这一切的是最初在第 1 列中匹配的两个填充,我使用了以下内容:
  • 再次抱歉。与 cmets 有问题。开始这一切的最初是第 1 列中匹配的两个文件,我使用 awk 在匹配时交换两列。 'awk 'FNR==NR{a[$1]=$4;next} $1 in a{$4=a[$1]}1' file1 file2 > file3' 当第一个报告更改并删除不再起作用的尾随数字时。
【解决方案2】:

这可能对你有用(GNU sed):

sed -r 's|^(\S+)(\s(\S+)){3}\s.*|/^\1/s/\\S+/\3/4|' file2 | sed -rf - -i file1

这会从 file2 创建一个 sed 脚本,然后针对 file1 运行它。

从 file2 生成的 sed 脚本使用第一列值匹配目标文件中的一行,然后将目标文件中的第四列替换为其第四列中的值。

【讨论】:

  • 谢谢。我选择了 awk 解决方案,因为它接近我已经使用的解决方案。但是,您的建议让我以一些新的方式思考我正在运行的其他一些脚本,我需要看看这些脚本。再次感谢。
猜你喜欢
  • 2019-11-19
  • 2021-11-17
  • 2013-06-26
  • 2017-10-25
  • 1970-01-01
  • 1970-01-01
  • 2015-08-07
  • 2020-08-20
  • 2011-12-12
相关资源
最近更新 更多