Perl — как анализировать нулевые значения в файле .tsv

Я использую Perl для анализа электронной таблицы Excel, которую я преобразовал в текстовый файл с разделителями табуляции. Я хочу написать цикл if, который зависит от наличия значения в определенном столбце, но пустые значения приводят к сбою моего кода.

Вот как выглядит файл tsv:

Patient No.     Date      Freezer   Location        Description     Frozen @ Passage
PT101           12/29/09  F1,-130   P-3,68          SERUM                                   
PT101           2/16/10   F1,-130   Q-9,62          Omentum         4                                       
PT101           2/16/10   F1,-130   Q-9,63          Omentum         4                                       
PT101                     F1,-130   O-3,8           L Ovary Tumor                                   

Обратите внимание, что в некоторых строках есть пустые ячейки.

Вот код:

#!/usr/bin/perl
use strict;
use warnings;
my $file = shift @ARGV;
open( FILE, $file );
while (<FILE>) {
    my $line = $_;
    chomp $line;
    my @c = split( "\t", $line );
    my $p = $c[5];
    if ( $p !~ /\d/ ) { next; }    # this value will be a number if it is present
    print "$line\n";
}
close FILE;

Когда я запускаю это, я получаю сообщение об ошибке, жалующееся на неинициированные значения, сбивающие с толку оператор Regex if. Есть ли оператор if, который я могу использовать для проверки неинициированных значений? Есть ли другой способ написать оператор if, основанный на наличии значения в 6-м столбце?

Примечание. Я рассматривал возможность использования функции pop для получения самого правого значения и проверки того, является ли значение числом, но это нежелательно, поскольку в моем примере есть больше столбцов справа от столбцов, которые иногда числовые, иногда текстовые, а иногда и пустые.


person Slavatron    schedule 15.10.2014    source источник
comment
Обратите внимание, что вы можете читать Excel напрямую (с соответствующим модулем CPAN), избегая преобразования в CSV.   -  person Miguel Prz    schedule 15.10.2014
comment
Не используйте для этого регулярные выражения. Используйте модуль Text::CSV или Text::CSV_XS.   -  person Andy Lester    schedule 15.10.2014
comment
@Slavatron Было бы безопаснее просто сохраните таблицу в формате CSV.   -  person ThisSuitIsBlackNot    schedule 16.10.2014


Ответы (1)


Есть ли оператор if, который я могу использовать для проверки неинициированных значений? Есть ли другой способ написать оператор if, основанный на наличии значения в 6-м столбце?

Есть множество способов сделать это. Вы можете использовать оператор «undefined-or» (//)

next unless ( $p // '' ) =~ /\d/;

Или вы можете просто проверить определенность:

next unless defined( $p ) && $p =~ /\d/;

Если бы '0' не была допустимой строкой цифр, вы могли бы просто проверить «ложность», например:

next unless $p && $p =~ /\d/;

Однако я решил попытаться показать вам, как это сделать с помощью Text::CSV:

my $csv = Text::CSV->new ({ sep_char => "\t" });    
while ( my $line = <FILE> ) {
    chomp $line;
    next unless $line;
    die $csv->error_diag 
        unless $csv->parse( $line )
        ;
    next unless defined( my $p = ( $csv->fields )[5] );
    next unless $p =~ /\d/;
    say $line;
}
person Axeman    schedule 15.10.2014