AWK:确认连续行的匹配列

时间:2017-02-02 20:32:17

标签: linux awk compare

您好,感谢您抽出宝贵时间阅读此问题。在最后一天,我一直试图解决问题,并且没有更接近解决方案。我有一个包含以下内容的示例数据文件:

Fighter@Trainer
Bobby@SamBonen
Billy@BobBrown
Sammy@DJacobson
James@DJacobson
Donny@SonnyG
Ben@JasonS
Dave@JuanO
Derrek@KMcLaughlin
Dillon@LGarmati
Orson@LGarmati
Jeff@RodgerU
Brad@VCastillo

目标是确定拥有多个战斗机的“训练师”。我的直觉是“getline”和AWK中的变量声明指令将是需要的。我尝试过不同的

组合
awk -F@ 'NR>1{a=$2; getline; if($2 = a) {print $0,"Yes"} else {print $0,"NO"}}' sample.txt

然而,产出远不及预期的结果。实际上,它甚至不输出示例文件中的所有行!

我想要的结果是:

Fighter@Trainer
Bobby@SamBonen@NO
Billy@BobBrown@NO
Sammy@DJacobson@YES
James@DJacobson@YES
Donny@SonnyG@NO
Ben@JasonS@NO
Dave@JuanO@NO
Derrek@KMcLaughlin@NO
Dillon@LGarmati@YES
Orson@LGarmati@YES
Jeff@RodgerU@NO
Brad@VCastillo@NO

我完全迷失了从哪里开始。我一直在寻找并试图找到一个无济于事的解决方案,我正在寻找一些意见。谢谢!

2 个答案:

答案 0 :(得分:4)

您不需要getline。 你可以正常处理输入, 建立每个培训师的计数, 并将结果打印在END块中:

awk -F@ '{
  lines[NR] = $0;
  trainers[NR] = $2;
  counts[$2]++;
}
END {
  print lines[1];
  for (i = 2; i <= length(lines); i++) {
    print lines[i] "@" (counts[trainers[i]] > 1 ? "YES" : "NO");
  }
}' sample.txt

答案 1 :(得分:1)

另一种选择是两次通过:

$ cat p.awk
BEGIN {FS=OFS="@"}
NR==1 {print;next};
NR==FNR {++trainers[$2]; next}
FNR>1 {$3=(trainers[$2]>1)?"YES":"NO"; print}

$ awk -f p.awk p.txt p.txt
Fighter@Trainer
Bobby@SamBonen@NO
Billy@BobBrown@NO
Sammy@DJacobson@YES
James@DJacobson@YES
Donny@SonnyG@NO
Ben@JasonS@NO
Dave@JuanO@NO
Derrek@KMcLaughlin@NO
Dillon@LGarmati@YES
Orson@LGarmati@YES
Jeff@RodgerU@NO
Brad@VCastillo@NO

<强>解释

设置输入和输出文件分隔符:

BEGIN {FS=OFS="@"}

打印标题:

NR==1 {print;next};

第一次通过,计算每位培训师的出现次数:

NR==FNR {++trainers[$2]; next}

第二遍,根据训练计数设置YES或NO,打印结果:

FNR>1 {$3=(trainers[$2]>1)?"YES":"NO"; print}