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