2009-04-15 4 views
3

Мне нужно использовать Perl в среде Windows на работе, и мне нужно узнать количество строк, которые содержит большой файл csv (около 1.4Gb). Любая идея, как это сделать с минимальной потерей ресурсов?Как подсчитать количество строк в большом CSV-файле с помощью Perl?

Благодаря

PS Это должно быть сделано в сценарии Perl, и мы не разрешается устанавливать какие-либо новые модули в систему.

+1

«Не разрешается устанавливать новые модули», как правило, концептуальный миф. http://stackoverflow.com/questions/755168/perl-myths/755179#755179 –

ответ

9

Да, не используйте perl.

Вместо этого используйте простую утилиту для подсчета линий; wc.exe

Это часть набора окна утилиты перенесенных из Unix оригиналов.

http://unxutils.sourceforge.net/

Например;

PS D:\> wc test.pl 
    12  26  271 test.pl 
PS D:\> 

Где 12 == количество строк, 26 == количество слов, 271 == количество символов.

Если вам действительно нужно использовать perl;

D:\>perl -lne "END{print $.;}" < test.pl 
12 
+1

Несомненно, wc будет способом продолжить * nix, где он уже будет установлен, но действительно ли стоит загрузить отдельный исполняемый файл сделать что-то, что занимает короткую строку Perl? –

+0

Да, потому что Cygwin является обязательным для любой среды Windows. – KenE

+1

Это не Cygwin, а все-таки обязательный. Подсчет строк в файле - это такая общая деятельность, что определенно стоит использовать эту утилиту. –

14

Вы имеете в виду линии или строки? Ячейка может содержать разрывы строк, которые добавили бы строки в файл, но не строки. Если вам гарантировано, что никакие ячейки не содержат новые строки, просто используйте эту технику в Perl FAQ. В противном случае вам понадобится правильный синтаксический анализатор CSV, например Text::xSV.

+0

Прошу прощения, я имел в виду строки. –

+1

Вы должны изменить свой вопрос, поскольку каждый другой комментарий просто делает подсчет строк. – jiggy

+0

+1, хорошо, но стоит также упомянуть, что нет «официального» формата CSV - просто коллекция слабо определенных, несколько несовместимых форматов, которые не согласны с такими вещами, как процитировать запятые и разрешены ли разрывы строк в клетки. Многие инструменты предполагают 1 строку == 1. –

4
perl -lne "END { print $. }" myfile.csv 

Это только чтение по одной строке за раз, поэтому оно не теряет память, если каждая строка не очень длинная.

+0

Линии - это не то же самое, что строки CSV. Например, рассмотрим поля со встроенными новыми строками. –

+0

@brian: Это правда. Но также верно, что работа с CSV-файлами, содержащими поля со встроенными новыми линиями, обречена быть болезненной, потому что нет универсального соглашения между инструментами о том, следует ли кодировать такие вещи - к сожалению, CSV не является «стандартом». –

0

Упрощение для ответа edg, другой вариант - установить cygwin, чтобы получить wc и кучу других полезных утилит в Windows.

+0

IME, Cygwin добавляет слишком много осложнений, если вы не хотите запускать среду псевдо-UNIX. MinGW и MSYS обеспечивают более легкую весовую систему, которая хорошо работает для разработки программного обеспечения. Для простых инструментов командной строки GnuWin32 предлагает хороший набор инструментов с низким уровнем воздействия, простой установщик. – daotoad

+0

Спасибо за подсказку - я попробую их когда-нибудь! – KenE

+0

wc не является ответом, поскольку он подсчитывает строки, которые не совпадают с строкой CSV. См. Ответ Аксемана. –

3

Это один вкладыш обрабатывает новые строки в пределах строк:

  1. УЧИТЫВАЯ линию с нечетным количеством цитат.
  2. Учитывая, что двойные кавычки являются способом указания котировок в поле.
  3. У этого пользователя есть awesome флип-флоп оператор.

    perl -ne 'BEGIN{$re=qr/^[^"]*(?:"[^"]*"[^"]*)*?"[^"]*$/;}END{print"Count: $t\n";}$t++ unless /$re/../$re/' 
    

Рассмотрим:

  • wc не будет работать. Это потрясающе для подсчета строк, но не для строк CSV.
  • Вы должны установить - или бороться за установку - Text::CSV или какой-либо аналогичный стандартный пакет для правильной обработки.
  • Это может привести вас туда, тем не менее.


EDIT: Он запамятовал, что это окна:

perl -ne "BEGIN{$re=qr/^[^\"]*(?:\"[^\"]*\"[^\"]*)*?\"[^\"]*$/;}END{print qq/Count: $t\n/;};$t++ unless $pq and $pq = /$re/../$re/;" 

Странная вещь в том, что сломанную OS «оболочка интерпретирует && как условную Exec OS, и я не мог» не делай ничего, чтобы передумать! Если бы я сбежал от него, он просто передал бы это так, чтобы перл.

-1

я был идиотским, простой способ сделать это в скрипте:

open $extract, "<${extractFileName}" or die ("Cannot read row count of $extractFileName"); 
$rowCount=0;  
while (<$extract>) 
{ 
    $rowCount=$rowCount+1; 
} 

close($extract);