尽管已初始化,但未使用未初始化值时出错

时间:2018-01-17 03:14:11

标签: perl

我正在尝试制作一个查看一个输入文件内容的表,但它不断给我一个错误

lli

Use of uninitialized value $ac[3] in concatenation (.) or string at table.pl
    line 58 (#1)

虽然我做了几乎所有可能的更改但它仍然给我一个错误并且打印效果不佳。

这是我输入文件的样子:

Use of uninitialized value $or[2] in concatenation (.) or string at table.pl
    line 61 (#1)

这是我正在使用的脚本:

HEADER    OXIDOREDUCTASE                          08-JUN-12   2LU5              
EXPDTA    SOLID-STATE NMR                                                       
REMARK   2 RESOLUTION. NOT APPLICABLE.                                          
HETNAM     CU COPPER (II) ION 
HETNAM     ZN ZINC                                              
FORMUL   2   CU    CU 2+
FORMUL   2   ZN    ZN 2+                                                        
END   

这是它给我的输出,但它似乎打印不好,我真的不确定原因:

#!/usr/bin/env perl
use strict;
use warnings;
use diagnostics;

#my $testfile=shift;
open(INPUT, "$ARGV[0]") or die 'Cannot make it';
my @file=<INPUT>;
close INPUT;
my @ac=();
my @dr=();
my @os=();
my @or=();
my @fo=();

for (my $line=0;$line<=$#file;$line++)
{
    chomp($file[$line]);
    if ($file[$line] =~ /^HEADER/)
    {
        print( (split '\s+', $file[$line])[-1]);
        print "\t";

        while ($file[$line] !~ /^END /)
        {
            $line++;
            if ($file[$line]=~/^EXPDTA/)
            {
                $file[$line]=~s/^EXPDTA//;
                @os=(@os,split '\s+', $file[$line]);
            }
            if ($file[$line] =~ /^REMARK   2 RESOLUTION./)
            {
                $file[$line]=~s/^REMARK   2 RESOLUTION.//;
                @ac = (@ac,split'\s+',$file[$line]);
            }
            if ($file[$line] =~ /^HETNAM/)
            {
                $file[$line]=~s/^HETNAM//;
                $file[$line] =~ s/\s+//;
                push @dr, $file[$line];
            }
            if ($file[$line] =~ /^SOURCE   2 ORGANISM_SCIENTIFIC/)
            {
                $file[$line]=~s/^SOURCE   2 ORGANISM_SCIENTIFIC//;
                @or = (@or,split'\s+',$file[$line]);
            }
            if ($file[$line] =~ /^FORMUL/)
            {
                $file[$line]=~s/^FORMUL//;
                $file[$line] =~ s/\s+//;
                push @fo, $file[$line];
            }
        }
        print "$os[1] $os[2]\t";
        print "\t";
        @os=();
        print "$ac[3] $ac[4]\t" or die "Cannot be printed"; #line 58
        print "\t";
        @ac=();
        print "$or[2] $or[3]\t" or die "Cannot be printed";  #line 61
        print "\t";
        @or=();
        foreach (@dr)
        {
            print "$_";
            print "\t\t\t\t\t";
        }
        @dr=();
        print "\n";
    }
}

我期望的输出是:

2LU5    SOLID-STATE NMR                     CU COPPER (II) ION 

1 个答案:

答案 0 :(得分:1)

错误的根源是:

#!/usr/bin/env perl

use strict;
use warnings;
use Data::Dumper;

my @ac = ();

my $str = "REMARK   2 RESOLUTION. NOT APPLICABLE.   ";
$str =~ s/^REMARK   2 RESOLUTION.//;
@ac = ( @ac, split '\s+', $str );
print Dumper \@ac;

@ac的内容是:

$VAR1 = [
          '',
          'NOT',
          'APPLICABLE.'
        ];

没有$ac[3],你只有元素0,1,2。

如果您出现@or错误,则表示您没有匹配任何行:/^SOURCE 2 ORGANISM_SCIENTIFIC/

因此该数组为空,这也意味着您没有$or[2]来打印。

更一般地说 - 你在这里做的事实上非常笨重,并且有一个更清洁的解决方案。

怎么样:

#!/usr/bin/env perl

use strict;
use warnings;

#set the text "END" as our record separator
local $/ = 'END';

#define the fields to print out. 
my @field_order = qw ( HEADER EXPDTA REMARK HETNAM FORMUL ); 

print join ( ",", @field_order), "\n"; #print header row

#iterate STDIN or file named on command line.
#just like you're doing with open (FILE, $ARGV[0]) 
while ( <> ) {
   #select key value pairs into a hash - first word on the line is the 'key'
   #and the value is 'anything else'. 
   my %this_entry = m/^(\w+)\s+(.*)$/gm;
   next unless $this_entry{'HEADER'}; #check we have a header.

   s/\s+/ /g for values %this_entry; #strip repeated spaces from fields; 
   s/\s+$//g for values %this_entry; #strip trailing whitespace. 

   #split 'header' row into separate subfields
   #this is an example of how you could transform other fields. 
   ($this_entry{'HEADER'}, $this_entry{'DATE'}, $this_entry{'STRUCT'} ) = split ' ', $this_entry{'HEADER'};


   print join (",", @this_entry{@field_order} ), "\n";
}

这将 - 给你输入 - 打印:

HEADER,DATE,STRUCT,EXPDTA,REMARK,HETNAM,FORMUL
OXIDOREDUCTASE,08-JUN-12,2LU5,SOLID-STATE NMR,2 RESOLUTION. NOT APPLICABLE.,CU COPPER (II) ION,2 CU CU 2+

这与您的输出匹配的并不完全相同,但希望它说明了这个任务可以简化多少?