Perl-скрипт (или что-то еще) для суммирования столбца CSV - PullRequest
2 голосов
/ 12 ноября 2010

Я написал (с большой помощью от других) команду awk для суммирования столбца в файле CSV.К сожалению, я узнал после некоторого поиска в Google, что awk не очень хорош в обработке файлов CSV из-за того, что разделитель не всегда одинаков (т.е. запятые следует игнорировать, когда они заключены в кавычки).Кажется, что, возможно, сценарий Perl мог бы сделать лучше.Возможно ли иметь однострочный сценарий Perl (или что-то почти такое же лаконичное), который выполняет то же самое, что и эта команда awk, которая суммирует 5-й столбец файла CSV?В частности, я не женат на Perl, но я надеялся избежать написания полноценного PHP-скрипта.К этому времени я мог бы легко написать сценарий PHP, но теперь, когда я зашел так далеко, я хочу посмотреть, смогу ли я выполнить его до конца.

Ответы [ 5 ]

6 голосов
/ 12 ноября 2010

Вам необходимо использовать приличный парсер CSV, чтобы справиться со всеми сложностями формата CSV. Text :: CSV_XS (или Text :: CSV , если это не доступно) - один из предпочтительных.

perl -e '{use Text::CSV_XS; my $csv=Text::CSV_XS->new(); open my $fh, "<", "file.csv" or die "file.csv: $!"; my $sum = 0; while (my $row = $csv->getline ($fh)) {$sum += $row->[4]}; close $fh; print "$sum\n";}'

Вот фактический код Perl, для лучшей читаемости

use Text::CSV_XS; # use the parser library
my $csv = Text::CSV_XS->new(); # Create parser object
open my $fh, "<", "file.csv" or die "file.csv: $!"; # Open the file. 
my $sum = 0; 
while (my $row = $csv->getline ($fh)) { # $row is array of field values now
    $sum += $row->[4];
}
close $fh; 
print "$sum\n";

Выше можно сократить, используя немного меньшее качество, но более плотный Perl :

cat file.csv | perl -MText::CSV_XS -nae '$csv=Text::CSV_XS->new(); 
               $csv->parse($_); @f=$csv->fields(); $s+=$f[4]} { print "$s\n"'
3 голосов
/ 12 ноября 2010

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

Учебник Фрагмент изменен для выполнения всего:

# ... some tutorial code ommited
while (<CSV>) {
    if ($csv->parse($_)) {
        my @columns = $csv->fields();
        $total += $columns[4];
    } else {
        my $err = $csv->error_input;
        print "Failed to parse line: $err";
    }
}
print "total: $total\n";
1 голос
/ 12 ноября 2010

Python

import csv
with open( "some_file.csv", "rb" ) as source:
    rdr= csv.reader( source )
    col_5= 0
    for row in rdr:
        col_5 += row[5]
print col_5

Не однострочник, но довольно кратко.

0 голосов
/ 13 ноября 2010

Довольно короткое (и быстрое) решение:

perl -MText::CSV_XS -E'$c=new Text::CSV_XS;$s+=$r->[4]while$r=$c->getline(*ARGV);say$s' file.csv
0 голосов
/ 12 ноября 2010

Есть ряд инструментов, которые делают это. Быстрый поиск «cli csvparser» привел меня к нескольким инструментам (с которыми я, по-видимому, не могу связать - возможно, для предотвращения спама).

Я установил первый найденный файл - csvtool - и смог выполнить командную строку, аналогичную вашей, и получить общую сумму.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...