Perl脚本(或任何内容)总计CSV列

Perl脚本(或任何内容)总计CSV列,perl,csv,awk,Perl,Csv,Awk,我(在其他人的帮助下)写了一篇文章,在CSV文件中总计一列。不幸的是,我通过谷歌搜索了解到,awk在处理CSV文件方面并不擅长,因为分隔符并不总是相同的(也就是说,用引号括起来时应该忽略逗号) 似乎Perl脚本可以做得更好。有没有可能使用一行Perl脚本(或几乎同样简洁的脚本)来实现与此awk命令相同的功能,该命令总计CSV文件的第5列 cat file.csv | awk -F "\"*,\"*" '{s+=$5} END {printf("%01.2f\n", s)}' 我不是特别喜欢Pe

我(在其他人的帮助下)写了一篇文章,在CSV文件中总计一列。不幸的是,我通过谷歌搜索了解到,
awk
在处理CSV文件方面并不擅长,因为分隔符并不总是相同的(也就是说,用引号括起来时应该忽略逗号)

似乎Perl脚本可以做得更好。有没有可能使用一行Perl脚本(或几乎同样简洁的脚本)来实现与此
awk
命令相同的功能,该命令总计CSV文件的第5列

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

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

您需要使用一个像样的CSV解析器来处理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模块吗?您可以使用来轻松地执行此操作,而无需滚动您自己的解析器

已更改代码段以执行总计:

# ... 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";
#。。。一些教程代码被删除了
而(){
如果($csv->parse($u2;)){
我的@columns=$csv->fields();
$total+=$columns[4];
}否则{
my$err=$csv->error\u输入;
打印“未能分析行:$err”;
}
}
打印“总计:$total\n”;
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

不是一行,而是非常简洁。

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

我安装了我发现的第一个工具——csvtool,并且能够执行与您类似的命令行,并获得一个总数。

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

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

我不知道Perl,但是在你的密集版本中,
{
看起来很奇怪。你不必提供的
-n
循环中是否隐含了
{
}
?你的
cat
版本与包含多行字符串字段的CSV文件不兼容。@Dennis-
}{foo
END{foo}
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
perl -MText::CSV_XS -E'$c=new Text::CSV_XS;$s+=$r->[4]while$r=$c->getline(*ARGV);say$s' file.csv