从txt文件中删除重复的行

我正在处理包含按行分隔的数据的大型文本文件(〜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

NB。 最后的顺序并不重要。

什么是有效的方法来做到这一点?

我可以使用awkpython或任何标准的linux命令行工具。

谢谢。

Solutions Collecting From Web of "从txt文件中删除重复的行"

以下(在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 ( 基于磁盘 )将其作为预处理步骤进行sort ,然后更改脚本,使其不会将整个文件读入内存。

awk '{x[$1 " " $2 " " $3] = $0} END {for (y in x) print x[y]}'

如果您需要指定不同文件的列数:

 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]} ' 

格兰·杰克曼的答案上的这种变化应该工作,不管有额外位的线的位置:

 awk '{idx = $1 " " $2 " " $3; if (length($0) > length(x[idx])) x[idx] = $0} END {for (idx in x) print x[idx]}' inputfile 

要么

 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 x[y]} ' inputfile 

这个或一个轻微的变体应该做的:

 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']} 

你必须定义一个函数把你的行分成重要的位和额外的位,然后你可以这样做:

 def split_extra(s): """Return a pair, the important bits and the extra bits.""" return blah blah blah data = {} for line in open('file'): impt, extra = split_extra(line) existing = data.setdefault(impt, extra) if len(extra) > len(existing): data[impt] = extra out = open('newfile', 'w') for impt, extra in data.iteritems(): out.write(impt + extra) 

因为你需要额外的位,所以最快的方法是创建一组唯一的条目(排序-u会做),然后你必须比较每个条目,例如

 if x.startswith(y) and not y.startswith(x) 

只留下x并丢弃y。

如果你有perl,只想保留最后一个条目:

 cat file.txt | perl -ne 'BEGIN{%k={}} @_ = split(/ /);$kw = shift(@_); $kws{$kw} = "@_"; END{ foreach(sort keys %kws){ print "$_ $kws{$_}";} }' > file.new.txt 

函数find_unique_lines将用于文件对象或字符串列表。

 import itertools def split_line(s): parts = s.strip().split(' ') return " ".join(parts[:3]), parts[3:], s def find_unique_lines(f): result = {} for key, data, line in itertools.imap(split_line, f): if data or key not in result: result[key] = line return result.itervalues() test = """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""".split('\n') for line in find_unique_lines(test): print line 
  BOB 123 1DB EXTRA BITS
 JIM 456 3DB AX
 DAVE 789 1DB