可以使用Perl的Text :: CSV_XS从CSV中删除列吗?

时间:2013-05-22 16:34:53

标签: perl csv

出于工作目的,我有几个CSV文件,这些文件已经过供应商升级修改,现在它们包含的列数比以前多了大约80个。缺点是,这些文件用于计费,因此我们需要修剪新列。好处是所有列都已添加到记录的末尾。旧记录包含251列。新记录包含336。

因此,我正在编写的脚本将接受CSV文件名作为参数,因为文件可能非常大,删除前两行和最后一行,最后删除新列(不仅仅是清空它们的内容,完全删除它们,所以如果原始格式有N列,处理后的新格式应该只有N列)

这是我到目前为止所做的:

use strict;
use warnings;

#Use Tie::File to modify file contents directly on disk, without reading
#to memory.
use Tie::File;

#Use Text::CSV_XS to quickly remove columns from CSV. External library
#used to compensate for quoted fields.
use Text::CSV_XS;

my $csvparser = Text::CSV_XS->new () or die "".Text::CSV_XS->error_diag();
my $file;

foreach $file (@ARGV){
        my @CSVFILE;
        my $csvparser = Text::CSV_XS->new () or die "".Text::CSV_XS->error_diag();
        tie @CSVFILE, 'Tie::File', $file or die $!;
        shift @CSVFILE;
        shift @CSVFILE;
        pop @CSVFILE;
        for my $line (@CSVFILE) {
                $csvparser->parse($line);
                my @fields = $csvparser->fields;
                splice @fields, -85;
                $line = $csvparser->combine(@fields);
        }

        untie @CSVFILE;
}

这将运行,第一部分正确运行(删除前两行和最后一行)。但是,我不确定如何继续删除新列。我一直在阅读Text :: CSV_XS的文档,我似乎找不到任何会删除列的函数。有些例子可能会有所帮助,但我承认我的perl技能并不是很好。我想要使​​用该模块的主要原因是这些CSV文件偶尔会包含带逗号的字段,用引号括起来,模块可以处理。

任何关于如何处理此问题的建议都会很精彩。如果我的方法有问题,请告诉我。我绝不是一个perl专家,并且对任何有用的批评持开放态度,因为这将被投入到计费系统中。

编辑:将以下建议纳入代码。如下所述,在运行此文件时,源文件的内容将在每一行上替换为单个“1”。

1 个答案:

答案 0 :(得分:4)

是的,你可以做你所要求的,虽然我不希望任何速度。

这样的事情应该有效

use strict;
use warnings;

use Tie::File;
use Text::CSV_XS;

my $csv = Text::CSV_XS->new or die Text::CSV_XS->error_diag;

foreach my $file (@ARGV) {

    tie my @lines, 'Tie::File', $file or die $!;

    splice @lines, 0, 2;
    pop @lines;

    for my $line (@lines) {
        $csv->parse($line);
        my @fields = $csv->fields;
        splice @fields, -80;
        $csv->combine(@fields);
        $line = $csv->string;
    }

    untie @lines;
}