2014-01-06 22 views
1

我必须读取CSV文件abc.csv,从中选择几个字段并形成一个新的CSV文件def.csv忽略使用Perl的CSV文件中的空行

以下是我的代码。我试图忽略来自abc.csv的空行。

genNewCsv(); 

sub genNewCsv { 
    my $csv = Text::CSV->new(); 
    my $aCsv = "abc.csv" 
    my $mCsv = "def.csv"; 
    my $fh = FileHandle->new($aCsv, "r"); 
    my $nf = FileHandle->new($mCsv, "w"); 

    $csv->print($nf, [ "id", "flops""ub" ]); 
    while (my $row = $csv->getline($fh)) { 

     my $id = $row->[0]; 

     my $flops = $row->[2]; 
     next if ($id =~ /^\s+$/); #Ignore empty lines 

     my $ub = "TRUE"; 
     $csv->print($nf, [ $id, $flops, $ub ]); 
    } 
    $nf->close(); 
    $fh->close(); 
} 

,但我得到了以下错误:

Use of uninitialized value $flops in pattern match (m//)

我怎么忽略空行的CSV文件?

我已经使用堆栈溢出问题Remove empty lines and space with Perl,但它没有帮助。

+0

fyi,你似乎在“flops”和“ub”之间缺少一个逗号 – Gabs00

+0

将'next if ...'移动一行,因为如果行是Cañons访问元素。 – smartmeta

+0

添加到@ Gabs00中,您有更多'syntax'错误:'my $ aCsv =“abc.csv”'缺少';'。复制粘贴错误? – chrsblck

回答

1

可以跳过整行,如果任何字段为空:

unless(defined($id) && defined($flop) && defined($ub)){ 
    next; 
} 

你测试过,如果$ ID是空的,但不是$响声,这就是为什么你得到了错误。

你也应该能够做到

unless($id && $flop && $ub){ 
    next; 
} 

在那里,一个空字符串将评估为false。

编辑:现在我想到了,你的意思是忽略那些不在那里的线?

你也可以做到这一点

my $id = $row[0] || 'No Val' #Where no value is anything you want to signify it was empty 

这将显示一个默认值的变量,如果第一个值结果为假。

0

运行这对您的文件第一次获得非空行

sub removeblanks { 
    my @lines =(); 
    while(@_) { 
     push @lines, $_ unless($_ =~ /^\s*$/); #add any other conditions here 
    } 
    return \@lines; 
} 
0

你可以做以下跳过空行:

while (my $row = $csv->getline($fh)){ 
    next unless grep $_, @$row; 
    ... 
1

你可以使用List::MoreUtils来检查是否有任何的字段的定义如下:

use List::MoreUtils qw(any); 
while(my $row = ...) { 
    next unless any { defined } @{ $row }; 
    ... 
}