从文本文件中删除重复行

5 投票
8 回答
7375 浏览
提问于 2025-04-16 11:31

我正在处理一些很大的文本文件(大约20MB),里面的数据是按行分隔的。

大部分数据条目都是重复的,我想去掉这些重复的,只保留一份。

而且,为了让问题稍微复杂一点,有些条目是重复的,但后面多了一些额外的信息。在这种情况下,我需要保留包含额外信息的条目,删除旧版本。

比如说,我需要把这个:

BOB 123 1DB
JIM 456 3DB AX
DAVE 789 1DB
BOB 123 1DB
JIM 456 3DB AX
DAVE 789 1DB
BOB 123 1DB EXTRA BITS

变成这个:

JIM 456 3DB AX
DAVE 789 1DB
BOB 123 1DB EXTRA BITS

注意,最后的顺序并不重要。

有没有什么有效的方法可以做到这一点?

我可以使用awk、python或者任何标准的Linux命令行工具。

谢谢。

8 个回答

2

这个或者稍微改动一下就可以了:

finalData = {}
for line in input:
    parts = line.split()
    key,extra = tuple(parts[0:3]),parts[3:]
    if key not in finalData or extra:
        finalData[key] = extra

pprint(finalData)

输出结果是:

{('BOB', '123', '1DB'): ['EXTRA', 'BITS'],
 ('DAVE', '789', '1DB'): [],
 ('JIM', '456', '3DB'): ['AX']}
3

这段代码是用来处理文本文件的,特别是用在Unix/Linux系统中的一个工具叫做awk。简单来说,它的作用是把文件中的每一行根据前面三列的内容进行分组,然后输出这些行。

具体来说,代码的意思是:首先,创建一个叫做x的数组,数组的键是每一行的前面三列的内容(用空格连接起来),而数组的值则是整行的内容。接着,在处理完所有行之后,代码会把数组中的所有值(也就是整行内容)打印出来。

如果你需要处理不同文件中列的数量,可以参考下面的代码:

awk -v ncols=3 '
  {
    key = "";
    for (i=1; i<=ncols; i++) {key = key FS $i}
    if (length($0) > length(x[key])) {x[key] = $0}
  }
  END {for (y in x) print y "\t" x[y]}
'
12

下面这个是用Python写的:

prev = None
for line in sorted(open('file')):
  line = line.strip()
  if prev is not None and not line.startswith(prev):
    print prev
  prev = line
if prev is not None:
  print prev

如果你觉得内存使用有问题,可以先用Unix的sort命令进行排序(这个是基于硬盘的),然后修改你的脚本,让它不需要把整个文件都读到内存里。

撰写回答