Какой лучший способ прочитать огромный CSV-файл с помощью Perl? - PullRequest
0 голосов
/ 01 февраля 2010

Требования

  • У меня есть очень большой файл CSV для чтения. (около 3 ГБ)
  • Мне не понадобятся все записи, я имею в виду, что есть некоторые условия, которые мы можем использовать, например, если содержимое 3-го столбца CSV имеет «XXXX», а 4-й столбец - «999».

Вопрос: Могу ли я использовать эти условия для улучшения процесса чтения? Если да, то как я могу это сделать с помощью Perl?

Мне нужен пример (Perl Script) в вашем ответе.

Ответы [ 5 ]

13 голосов
/ 01 февраля 2010

Вот решение:

#!/usr/bin/env perl
use warnings;
use strict;
use Text::CSV_XS;
use autodie;
my $csv = Text::CSV_XS->new();
open my $FH, "<", "file.txt";
while (<$FH>) {
    $csv->parse($_);
    my @fields = $csv->fields;
    next unless $fields[1] =~ /something I want/;
    # do the stuff to the fields you want here
}
5 голосов
/ 01 февраля 2010

Ваш a) на вопрос уже отвечали несколько раз, но b) еще не решен:

Мне не нужны все записи, я имею в виду, Есть некоторые условия, которые мы можно использовать, например, если 3-й CSV содержание столбца имеет «XXXX» и 4-й столбец имеет «999». Могу ли я использовать эти условия для улучшения чтения процесс

Нет. Как вы узнаете, содержит ли 3-й столбец CSV «XXXX» или 4-й «999», не читая сначала строку? (DBD :: CSV позволяет скрыть это за предложением SQL WHILE, но, поскольку CSV - это неиндексированные данные, ему все равно нужно читать каждую строку, чтобы определить, какие условия соответствуют, а какие нет.)

Практически единственный способ использования содержимого строки, позволяющей пропустить чтение частей файла, - это если он содержит информацию, сообщающую вам: 1) «пропустить раздел, следующий за этой строкой» и 2) «продолжить чтение с байта» смещение nnn ".

5 голосов
/ 01 февраля 2010

Использование Текст :: CSV

4 голосов
/ 01 февраля 2010

Модуль Text :: CSV является отличным решением для этого. Другой вариант - это модуль DBD :: CSV , который предоставляет немного другой интерфейс. Интерфейс DBI действительно полезен, если вы разрабатываете приложения, которым требуется доступ к данным из разных форм баз данных, включая реляционные базы данных и текстовые файлы, разделенные запятыми.

Вот пример кода:

#!/usr/bin/perl

use strict;
use warnings;
use DBI;

$dbh = DBI->connect ("DBI:CSV:f_dir=/home/joe/csvdb") 
    or die "Cannot connect: $DBI::errstr";

$sth = $dbh->prepare ("SELECT id, name FROM info.txt WHERE id > 1 ORDER by id");
$sth->execute;

my ($id,$name);
$sth->bind_columns (\$id, \$name);
while ($sth->fetch) {
    print "Found result row: id = $id, name = $name\n";
}
$sth->finish;

Я бы использовал Text :: CSV для этой задачи, если вы не планируете общаться с другими типами баз данных, но в Perl TIMTOWDI , и это помогает узнать ваши варианты.

3 голосов
/ 01 февраля 2010

используйте модуль типа Text :: CSV, однако, если вы знаете, что ваши данные не будут иметь встроенных запятых и их простой формат CSV, то простого цикла while для итерации файла будет достаточно

while (<>){
  chomp;
  @s = split /,/;
  if ( $s[2] eq "XXXX" && $s[3] eq "999" ){
    # do something;
  } 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...