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

Awk 如果特定列中的值唯一,则仅输出行,awk,Awk,输入: 期望输出: line1 a gh line2 a dd line3 c dd line4 a gg line5 b ef 也就是说,我只想在列2中没有其他行包含相同值的情况下输出行。我认为我可以通过组合使用sort来实现这一点,例如sort-k2,2输入和uniq,但是使用uniq,我似乎只能跳过左侧的列-f避免比较前N个字段。当然有一些简单的方法可以用awk或其他东西来实现这一点 您可以将awk、grep、sort和uniq组合成一个快速的单行程序: grep-v^[^]*$awk'

输入:

期望输出:

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

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

您可以将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

您可以通过两次awk脚本来完成:

line3 c dd
line5 b ef
当数组中的某个计数器的键是每行的第二个字段时,它会在文件中运行一次,然后第二次只打印计数器小于2的行

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

替代awk,以证明仍然可以使用sort和uniq执行此操作。对于此,有选项-u,然而,设置正确的格式需要一些复杂的装饰/做东西/取消装饰模式

awk 'NR==FNR{a[$2]++;next} a[$2]<2' file file
作为一个副作用,您会丢失原始排序顺序,如果添加行号,也可以恢复原始排序顺序…

这里有一个一次性awk解决方案:

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

line5 b ef
line3 c dd

但是,文件的原始顺序将丢失

你试过什么?我们这里的大多数人都很乐意帮助您改进您的技能,但不太乐意担任短期无薪编程人员。向我们展示你到目前为止的工作,你期望的结果和你得到的结果,我们会帮助你弄清楚。我以前从未见过像这样使用grep。^[^]*部分做什么?@5heikki第一个^将正则表达式锚定到行的前面,第二个^匹配所有不是空格的内容。因此在这种情况下,这将相当于grep-v^[^]*$echo a输入,但是,即使第四列只包含a,它仍然有效。我只是不明白为什么..如果匹配的文本包含RE元字符,你会发现@ghoti的答案仍然有效,而这个答案失败。idk,这对你的数据可能很好,但一般来说,从给定的样本输入中产生你期望的输出的答案是确定解决方案的起点,而不是终点-你必须真正思考每个答案实际上在做什么。哈哈,谢谢Ed,事实上,我去年在那篇文章上发表了评论。不是一次通过,是吗?第一次从磁盘读取文件,第二次从内存读取文件。@Graham:与awk{actions}文件相反,这是另一种方法。
awk '{a1[$2]++;a2[$2]=$0} END{for (a in a1) if (a1[a]==1) print a2[a]}' file