我有一个包含50,000条记录的40 MB csv文件。它是一个巨大的产品列表。每行有近20个字段。 [Item#,UPC,Desc等]
我怎么能,
a)查找并打印重复的行。 [这个文件是一个很大的附加文件,所以我需要删除文件中包含的多个标题,所以我想知道先重复的确切行。]
b)根据列查找并打印重复行。 [查看UPC是否分配给多个产品]
我需要在服务器上运行命令或脚本,并且我安装了Perl和Python。即使是bash脚本或命令也适用于我。
我不需要保留行的顺序。等等
我试过了,
sort largefile.csv | uniq -d
获得重复项,但我没有得到预期的答案。
理想情况下,我想要bash脚本或命令,但如果任何人有任何其他建议,那也会很棒。
由于
请参阅:Stack Overflow上的Remove duplicate rows from a large file in Python
答案 0 :(得分:8)
在Perl中查找并打印重复的行:
perl -ne 'print if $SEEN{$_}++' < input-file
在Perl中查找并打印包含重复列的行 - 假设第5列中的字段用逗号分隔:
perl -F/,/ -ane 'print if $SEEN{$F[4]}++' < input-file
答案 1 :(得分:8)
请尝试以下方法:
# Sort before using the uniq command
sort largefile.csv | sort | uniq -d
uniq是一个非常基本的命令,只报告彼此相邻的唯一性/重复。
答案 2 :(得分:2)
您可以使用SQLite shell导入csv文件并创建索引以更快地执行SQL命令。
答案 3 :(得分:1)
这里我的(非常简单)脚本用Ruby&amp;耙宝石。
首先创建 RakeFile 并编写此代码:
namespace :csv do
desc "find duplicates from CSV file on given column"
task :double, [:file, :column] do |t, args|
args.with_defaults(column: 0)
values = []
index = args.column.to_i
# parse given file row by row
File.open(args.file, "r").each_slice(1) do |line|
# get value of the given column
values << line.first.split(';')[index]
end
# compare length with & without uniq method
puts values.uniq.length == values.length ? "File does not contain duplicates" : "File contains duplicates"
end
end
然后在第一列
上使用它$ rake csv:double["2017.04.07-Export.csv"]
File does not contain duplicates
并在第二个(例如)
上使用它$ rake csv:double["2017.04.07-Export.csv",1]
File contains duplicates
答案 4 :(得分:0)
对于第二部分:使用Text :: CSV将文件读入键入您的唯一键的哈希值,在添加哈希值之前检查哈希值是否存在。像这样:
数据(不需要排序),在这个例子中我们需要前两列是唯一的:
1142,X426,Name1,Thing1
1142,X426,Name2,Thing2
1142,X426,Name3,Thing3
1142,X426,Name4,Thing4
1144,X427,Name5,Thing5
1144,X427,Name6,Thing6
1144,X427,Name7,Thing7
1144,X427,Name8,Thing8
代码:
use strict;
use warnings;
use Text::CSV;
my %data;
my %dupes;
my @rows;
my $csv = Text::CSV->new ()
or die "Cannot use CSV: ".Text::CSV->error_diag ();
open my $fh, "<", "data.csv" or die "data.csv: $!";
while ( my $row = $csv->getline( $fh ) ) {
# insert row into row list
push @rows, $row;
# join the unique keys with the
# perl 'multidimensional array emulation'
# subscript character
my $key = join( $;, @{$row}[0,1] );
# if it was just one field, just use
# my $key = $row->[$keyfieldindex];
# if you were checking for full line duplicates (header lines):
# my $key = join($;, @$row);
# if %data has an entry for the record, add it to dupes
if (exists $data{$key}) { # duplicate
# if it isn't already duplicated
# add this row and the original
if (not exists $dupes{$key}) {
push @{$dupes{$key}}, $data{$key};
}
# add the duplicate row
push @{$dupes{$key}}, $row;
} else {
$data{ $key } = $row;
}
}
$csv->eof or $csv->error_diag();
close $fh;
# print out duplicates:
warn "Duplicate Values:\n";
warn "-----------------\n";
foreach my $key (keys %dupes) {
my @keys = split($;, $key);
warn "Key: @keys\n";
foreach my $dupe (@{$dupes{$key}}) {
warn "\tData: @$dupe\n";
}
}
打印出类似这样的内容:
Duplicate Values:
-----------------
Key: 1142 X426
Data: 1142 X426 Name1 Thing1
Data: 1142 X426 Name2 Thing2
Data: 1142 X426 Name3 Thing3
Data: 1142 X426 Name4 Thing4
Key: 1144 X427
Data: 1144 X427 Name5 Thing5
Data: 1144 X427 Name6 Thing6
Data: 1144 X427 Name7 Thing7
Data: 1144 X427 Name8 Thing8