Скрипт для поиска дубликатов в CSV-файле - PullRequest
9 голосов
/ 04 ноября 2010

У меня есть 40 МБ CSV-файл с 50000 записей.Это гигантский список продуктов.Каждый ряд имеет около 20 полей.[Item #, UPC, Desc и т. Д.]

Как я могу,

a) Найти и напечатать повторяющиеся строки.[Этот файл является большим приложенным файлом, поэтому в файл включены несколько заголовков, которые мне нужно удалить, поэтому я хотел узнать точные строки, которые сначала дублируют друг друга.]

b) Найти и напечатать дублирующиеся строкина основе столбца.[Посмотреть, назначен ли UPC нескольким продуктам]

Мне нужно запустить команду или скрипт на сервере, и у меня установлены Perl и Python.Даже сценарий или команда bash будут работать и для меня.

Мне не нужно сохранять порядок строк.etc

Я пробовал,

sort largefile.csv |uniq -d

, чтобы получить дубликаты, но я не получаю ожидаемого ответа.

В идеале я хотел бы использовать bash-скрипт или команду, но если у кого-то есть какие-либо другие предложения, это тоже было бы здорово.

Спасибо


См .: Удалите повторяющиеся строки из большого файла в Python поверх Stack Overflow

Ответы [ 5 ]

8 голосов
/ 11 сентября 2013

Попробуйте следующее:

# Sort before using the uniq command
sort largefile.csv | sort | uniq -d

uniq - очень простая команда, которая сообщает об уникальности / дубликатах, которые расположены рядом друг с другом .

8 голосов
/ 04 ноября 2010

Поиск и печать повторяющихся строк в Perl:

perl -ne 'print if $SEEN{$_}++' < input-file

Поиск и печать строк с повторяющимися столбцами в Perl - скажем, 5-й столбец, где поля разделены запятыми:

perl -F/,/ -ane 'print if $SEEN{$F[4]}++' < input-file
2 голосов
/ 04 ноября 2010

Вы можете использовать оболочку SQLite для импорта файла CSV и создания индексов для более быстрого выполнения команд SQL.

1 голос
/ 07 апреля 2017

Вот мой (очень простой) скрипт для этого с Ruby & Rake Gem.

Сначала создайте 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
0 голосов
/ 04 ноября 2010

Для второй части: прочитайте файл с 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...