【问题标题】:Lookup and Replace with two files in awk用 awk 中的两个文件查找和替换
【发布时间】:2013-12-23 01:31:33
【问题描述】:

我正在尝试用一行 AWK 代码更正一个文件与另一个文件。我试图从 FILE2 中取出 $1,在 FILE1 中查找,得到相应的 $3 和 $4。将它们设置为变量后,我希望程序停止评估 FILE1,将 $10 和 $11 从 FILE2 更改为变量的值,然后打印出来。

提取变量后,我无法让 awk 从 FILE1 切换到 FILE2。我已经尝试过 nextfile,但这会重置程序并且它会厌倦从 FILE2 中提取变量,我将 NR 设置为最后一个记录,但它没有切换。

我也在做一个循环来从 FILE1 中取出每一行,但如果这可以成为脚本的一部分,我相信它会加快速度,而不必一遍又一遍地重新打开 awk。

这是我想出来的部分。

for file in `cut -f 1 FILE2`; do
awk -v a=$file '$1=a{s=$2;q=$4; ---GO TO FILE1---}{if ($1==a) {$10=s; $11=q; print 0;exit}' FILE1 FILE2 >> FILEOUT
done

一个快速示例集注意:尽管我是这样写的,但这两个文件的顺序不同,大小约为 8GB,因此排序有点笨拙。

文件1

A 12345 + AJD$JD
B 12504 + DKFJ#%
C 52042 + DSJTJE

文件2

A 2 3 4 5 6 7 8 9 345 D$J 
B 2 3 4 5 6 7 8 9 250 KFJ
C 2 3 4 5 6 7 8 9 204 SJT

文件

A 2 3 4 5 6 7 8 9 12345 AJD$JD 
B 2 3 4 5 6 7 8 9 12504 DKFJ#%
C 2 3 4 5 6 7 8 9 52042 DSJTJE

这是我根据下面肯特的回答开始工作的代码。

awk 'NR==FNR{a[$1]=$2" "$4;next}$1 in a{$9=$9" "a[$1]}{$10="";$11=""}2' f1 f2 

【问题讨论】:

  • 提供输入/输出示例将帮助您更快地得到答案。

标签: input awk gawk


【解决方案1】:

试试这个单线:

kent$  awk 'NR==FNR{a[$1]=$2" "$4;next}$1 in a{NF-=2;$0=$0" "a[$1]}7' f1 f2
A 2 3 4 5 6 7 8 9 12345 AJD$JD
B 2 3 4 5 6 7 8 9 12504 DKFJ#%
C 2 3 4 5 6 7 8 9 52042 DSJTJE

【讨论】:

  • 我在我的文件上检查了这个,我只是将未更改的 f2 作为输出。我认为一个问题是 F1 包含 F2 中的所有行,但反之则不然。我想我可以用全套试一试,看看会发生什么。
  • @user2348290 这应该不是问题。如果我的单行适用于它,你可以用你的问题中的小例子进行测试吗?
  • 好吧,我知道发生了什么(f1 中的 $1 在 $1 前面有一个 @)。我遇到的唯一问题是在 $11 之后有可选字段,这些字段有时存在,有时不存在(抱歉,我的示例中没有包含此内容)。我怎样才能让这个脚本用数组输入巧妙地替换 $10 和 $11?
  • 好的,所以我编辑了代码来做我想做的事。我已经把它放在原来的帖子里了。但我不明白其中的两个部分。第 1 部分:我不明白为什么在没有打印命令的情况下打印输出。第 2 部分(我认为这是我的第一个问题的一部分)语句末尾的数字“7”是什么意思。我将其更改为其他没有明显影响的数字。只是好奇
【解决方案2】:

无需重复遍历文件 - 只需读取一个文件并将相关字段存储在以$1 为键的数组中,然后浏览另一个文件并使用这些数组查找要插入的值。

awk '(FILENAME=="FILE1"){y[$1]=$2;z[$1]=$4}; (FILENAME=="FILE2" && $1 in y){$10=y[$1];$11=z[$1];print $0}' FILE1 FILE2

也就是说,听起来您可能在这里使用join 命令而不是乱用awk(上面的脚本假设您所有的$1/$2/$4 值都适合内存)。

【讨论】:

  • 快速提问,第二部分应该开始 "(FILENAME=="FILE2" && x[$1]==$1)" 吗?
  • 没有。 x 旨在成为一个数组,让我们可以轻松检查 FILE1 中存在哪些 $1 值。该数组中存在一个键这一事实很重要——存储在该键上的值是无关紧要的(我只是使用了常量1)。
  • 实际上,我的代码有点脑残 - 阅读其他答案让我想起了 in 运算符,我可能应该使用它。我已经编辑了我的答案以使用它并摆脱x - 希望该检查的意图现在很清楚。
  • 我仍在努力理解这一点(我很难掌握数组)。然而,我得到的输出没有 10 美元和 11 美元。
  • 上述描述不准确。如果我设置了 FILENAME==FILE1 和 FILENAME==FILE2,我不会得到任何输出。当我使它们相同时,我得到文件不变(如果我更正放入数组中的列。
猜你喜欢
  • 2018-02-06
  • 1970-01-01
  • 2014-07-07
  • 2014-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-03
  • 2017-11-11
相关资源
最近更新 更多