删除重复行而不进行排序

时间:2012-07-17 23:14:11

标签: shell scripting filter uniq

我在Python中有一个实用程序脚本:

#!/usr/bin/env python
import sys
unique_lines = []
duplicate_lines = []
for line in sys.stdin:
  if line in unique_lines:
    duplicate_lines.append(line)
  else:
    unique_lines.append(line)
    sys.stdout.write(line)
# optionally do something with duplicate_lines

这个简单的功能(uniq无需先排序,稳定排序)必须作为简单的UNIX实用程序提供,不是吗?也许是管道中过滤器的组合?

询问的原因:在我无法从任何地方执行python的系统上需要此功能

8 个答案:

答案 0 :(得分:213)

UNIX Bash Scripting博客suggests

awk '!x[$0]++'

这个命令告诉awk要打印哪些行。变量$0保存一行的全部内容,方括号是数组访问。因此,对于文件的每一行,数组x的节点会递增,如果该节点的内容不是(!)之前设置的,则打印该行。

答案 1 :(得分:52)

迟到的答案 - 我刚刚碰到了这个副本 - 但也许值得补充......

@ 1_CR答案背后的原则可以更简洁地编写,使用cat -n代替awk来添加行号:

cat -n file_name | sort -uk2 | sort -nk1 | cut -f2-
  • 使用cat -n添加行号
  • 使用sort -u删除重复数据
  • 使用sort -n按前缀数字排序
  • 使用cut删除行号

答案 2 :(得分:5)

迈克尔霍夫曼的解决方案是短暂而甜蜜的。对于较大的文件,Schwartzian变换方法涉及使用awk后跟多轮sort和uniq添加索引字段涉及较少的内存开销。以下代码段在bash中起作用

awk '{print(NR"\t"$0)}' file_name | sort -t$'\t' -k2,2 | uniq --skip-fields 1 | sort -k1,1 -t$'\t' | cut -f2 -d$'\t'

答案 3 :(得分:3)

从2个文件中删除重复:

awk '!a[$0]++' file1.csv file2.csv

答案 4 :(得分:2)

谢谢1_CR!我需要一个“uniq -u”(完全删除重复)而不是uniq(留下1份副本)。 awk和perl解决方案无法真正修改来做到这一点,你可以!我可能还需要较低的内存使用率,因为我将不会像100,000,000行8-)。为了防止其他人需要它,我只是在命令的uniq部分放了一个“-u”:

awk '{print(NR"\t"$0)}' file_name | sort -t$'\t' -k2,2 | uniq -u --skip-fields 1 | sort -k1,1 -t$'\t' | cut -f2 -d$'\t'

答案 5 :(得分:1)

现在你可以查看用Rust编写的这个小工具:uq

它执行唯一性过滤而无需先对输入进行排序,因此可以应用于连续流。

答案 6 :(得分:0)

我只想删除以下行中的所有重复项,而不是文件中的任何位置。所以我用过:

[DllImport("my.dll", CallingConvention = CallingConvention.Cdecl)]
static public extern void readText(out DataBlock dataBlock, string dataArray, int bytesToRead);

答案 7 :(得分:0)