出于工作目的,我有几个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”。
答案 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;
}