打印所有具有重复字段的行的最有效方法是什么?

打印所有具有重复字段的行的最有效方法是什么?

以下文件 fruit_notes.txt 有三个用竖线分隔的列:水果、颜色和品尝笔记。我想打印所有具有重复颜色字段的行。顺序并不重要。

banana|YELLOW|My turtle likes these.
cherry|RED|Sweet and tasty
grapefruit|YELLOW|Very juicy
grape|PURPLE|Yummy
lemon|YELLOW|Sour!
apple|RED|Makes great pie
orange|ORANGE|Oranges make me laugh.

这有效...

> grep -F "`awk -F"|" '{print $2}' fruit_notes.txt | sort | uniq -d`" fruit_notes.txt
banana|YELLOW|My turtle likes these
cherry|RED|Sweet and tasty
grapefruit|YELLOW|Very juicy
lemon|YELLOW|Sour!
apple|RED|Makes great pie

然而,这似乎是一个尴尬的(没有双关语的意思)解决方案。它读取文件两次:一次是在颜色字段中查找重复项,另一次是查找与重复颜色匹配的行。它也容易出错。例如,以下行将被错误地打印:

jalapeños|GREEN|My face turns RED when I eat these!

有没有更好的方法来做到这一点,也许单独使用 awk?

答案1

这会改变输出的顺序,但只需要读取文件一次:

$ awk -F'|' '$2 in a{if(a[$2])print a[$2];a[$2]=""; print; next} {a[$2]=$0}' fruit_notes.txt
banana|YELLOW|My turtle likes these.
grapefruit|YELLOW|Very juicy
lemon|YELLOW|Sour!
cherry|RED|Sweet and tasty
apple|RED|Makes great pie

怎么运行的:

  1. $2 in a{if(a[$2])print a[$2];a[$2]=""; print; next}

    如果$2是关联数组中的键a,则(a)如果a[$2]不为空,则打印它,(b)设置a[$2]为空,(c)打印当前行,(d)跳过其余命令并从下一行重新开始。

  2. a[$2]=$0

    如果这是我们第一次遇到$2,请将当前行保存在a键下$2

相关内容