Perl 脚本(或任何东西)来合计 CSV 列

发布于 2024-10-01 16:31:59 字数 545 浏览 2 评论 0原文

我(在其他人的大量帮助下)写了一个 awk 命令 对 CSV 文件中的列进行总计。不幸的是,我在谷歌搜索后了解到,awk 并不擅长处理 CSV 文件,因为分隔符并不总是相同(即逗号在引号引起来时应该被忽略)。

看起来也许 Perl 脚本可以做得更好。是否有可能有一个一行 Perl 脚本(或几乎同样简洁的脚本)来实现与此 awk 命令相同的功能,该命令总计 CSV 文件的第 5 列?

cat file.csv | awk -F "\"*,\"*" '{s+=$5} END {printf("%01.2f\n", s)}'

我并不是特别喜欢 Perl,但我希望避免编写成熟的 PHP 脚本。此时我已经可以轻松编写 PHP 脚本了,但现在我已经走到这一步了,我想看看我是否可以遵循它。

I wrote (with lots of help from others) an awk command to total up a column in a CSV file. Unfortunately, I learned after some Googling that awk isn't great at handling CSV files due to the fact that the separator is not always the same (i.e. commas should be ignored when surround by quotes).

It seems that perhaps a Perl script could do better. Would it be possible to have a one-line Perl script (or something nearly as succinct) that achieves the same thing as this awk command that totals up the 5th column of a CSV file?

cat file.csv | awk -F "\"*,\"*" '{s+=$5} END {printf("%01.2f\n", s)}'

I'm not married to Perl in particular but I was hoping to avoid writing a full-blown PHP script. By this time I could have easily written a PHP script, but now that I've come this far, I want to see if I can follow it through.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

謌踐踏愛綪 2024-10-08 16:31:59

您需要使用一个像样的 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"'

You need to use a decent CSV parser to deal with all the complexities of CSV format. Text::CSV_XS (or Text::CSV if that's not avialable) is one of the preferred ones.

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";}'

Here's the actual Perl code, for better readability

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";

The above could be shortened by using slightly lesser quality but denser 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"'
冷情 2024-10-08 16:31:59

您反对使用 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";

Are you opposed to using a Perl module? You can use Text::CSV to do this easily without rolling your own parser.

Tutorial snippet changed to perform total:

# ... 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";
温柔嚣张 2024-10-08 16:31:59

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

不是一句简单的话,但相当简洁。

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

Not a one-liner, but pretty terse.

情深如许 2024-10-08 16:31:59

有很多工具可以做到这一点。快速搜索“cli csvparser”让我找到了几个工具(我显然无法链接到这些工具——可能是为了防止垃圾邮件)。

我安装了我找到的第一个工具 - csvtool - 并且能够执行与您类似的命令行并获得总计。

There are a number of tools that do this. A quick search for 'cli csvparser' lead me to several tools (which I apparently can't link to--possibly to prevent spamming).

I installed the first one I found--csvtool--and was able to do a similar command line as yours and get a total.

夏有森光若流苏 2024-10-08 16:31:59

非常短(且快速)的解决方案:

perl -MText::CSV_XS -E'$c=new Text::CSV_XS;$s+=$r->[4]while$r=$c->getline(*ARGV);say$s' file.csv

Pretty short (and fast) solution:

perl -MText::CSV_XS -E'$c=new Text::CSV_XS;$s+=$r->[4]while$r=$c->getline(*ARGV);say$s' file.csv
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文