可以使用Perl';s Text::CSV_XS是否用于从CSV中删除列?

可以使用Perl';s Text::CSV_XS是否用于从CSV中删除列?,perl,csv,Perl,Csv,出于工作目的,我有几个CSV文件,这些文件已通过供应商升级进行了修改,现在它们包含的列比以前多了大约80列。缺点是,这些文件用于计费,因此我们需要删除新列。上边是所有列都已添加到记录的末尾。旧记录包含251列。新记录包含336条 因此,我正在编写的脚本将接受CSV文件名作为参数,对其进行适当编辑,因为文件可能非常大,删除前两行和最后一行,最后删除新列(不只是清空它们的内容,还要完全删除它们,因此如果原始格式有N列,则处理后的新格式应该只有N列) 以下是我到目前为止的情况: use strict;

出于工作目的,我有几个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::csvxs的文档,似乎找不到任何可以删除列的函数。其中一些示例可能会有所帮助,但我承认我的perl技能不是很好。我想使用该模块的主要原因是这些CSV文件没有通常包含带逗号的字段,并用引号括起来,模块可以处理这些字段

关于如何实现这一点的任何建议都将是非常好的。如果我的方法有问题,请让我知道。我绝不是perl专家,我愿意接受任何有益的批评,因为这将被输入到计费系统中


编辑:将下面的建议包含到代码中。如下所述,当运行此命令时,源文件的内容在每一行上都被替换为一个“1”。

是的,您可以按要求执行,尽管我不希望速度太快

像这样的东西应该有用

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

这是正确的,但是执行此操作后,文件中充满了“1”s、 我已经用新的代码更新了这个问题。我感谢你迄今为止的帮助!@Matthew:对不起,我的IDE和这篇文章之间似乎发生了意外。有一行代码丢失。现在应该可以正常工作了。与其删除后面的80列,我更希望这段代码保留特定数量的列。但是你不同意删除不需要的80后应该剩下多少列。大概您知道,因此您可以用该数字替换
-80
。最终目标是只有251列,如前所述,供应商升级增加了85列,使新的总数为336列。我们的计费系统设置为处理该数量的字段,并且遇到了问题添加了新的变量。啊,好吧,那么你想要
splice@fields,251
请不要对Perl局部变量使用大写字母。它们是为全局名称保留的,比如
@ARGV
Text::CSV_XS
。根据旧的驼峰手册,我的印象是,标准是对文件句柄使用所有大写字母这种风格改变了??旧式的文件句柄也是全局的,所以所有的caps都是全局的。当前的最佳实践是对文件句柄使用词法标量变量,所以现在是
openmyfh,'