如果特定列中的值是唯一的,则仅输出行

时间:2016-03-10 12:28:40

标签: awk

输入:

line1 a gh
line2 a dd
line3 c dd
line4 a gg
line5 b ef

期望的输出:

line3 c dd
line5 b ef

也就是说,我想仅在第2列中没有其他行包含相同值的情况下输出行。我认为我可以通过组合排序(例如sort -k2,2输入)和uniq来实现这一点,但似乎使用uniq我只能跳过左边的列(-f避免比较前N个字段)。当然有一些直接的方法来使用awk或其他东西。

4 个答案:

答案 0 :(得分:3)

您可以将此作为两遍awk脚本执行此操作:

awk 'NR==FNR{a[$2]++;next} a[$2]<2' file file

一旦递增一个数组中的计数器,其键是每行的第二个字段,然后再次运行,只打印那些计数器小于2的行。

您需要多次读取该文件,因为在第一次读取期间的任何时候,您都不可能知道文件后面是否会有该行的第二个字段的另一个实例。

答案 1 :(得分:2)

以下是一次通过awk解决方案:

awk '{a1[$2]++;a2[$2]=$0} END{for (a in a1) if (a1[a]==1) print a2[a]}' file

然而,文件的原始顺序将丢失。

答案 2 :(得分:1)

你可以将awk,grep,sort和uniq组合成一个快速的单行:

grep -v "^[^ ]* $(awk '{print $2}' input.txt | sort | uniq -d) " input.txt

编辑,以避免正则表达式,\ +和\ backreferences:

grep -v "^[^ ]* $(awk '{print $2}' input.txt | sort | uniq -d | sed 's/[^+0-9]/\\&/g') " input.txt

答案 3 :(得分:1)

替代awk以证明它仍然可以使用sort和uniq(这里有选项-u),但是设置正确的格式需要一些杂耍(装饰/做东西/ undecorate模式)。

$ paste file <(cut -d' ' -f2 file) | sort -k2 | uniq -uf3 | cut -f1

line5 b ef
line3 c dd

作为副作用,您将丢失原始排序顺序,如果您添加行号,也可以恢复...