为什么我的脚本只访问数组中的第一个元素?

时间:2015-03-09 15:54:59

标签: arrays perl

以下是我的脚本。 我尝试了许多print语句来解决为什么它只访问第一个数组元素。模式匹配有效。该阵列至少包含40个元素。我已经检查过,它已经满了。 我打印了每一行,每行打印。

my $index = 0;
open(FILE, "$file") or die "\nNot opening $file for reading\n\n";
open(OUT, ">$final") or die "Did not open $final\n";
while (<FILE>) {
    foreach my $barcode (@barcode) {
        my @line = <FILE>;
        foreach $_ (@line) {
            if ($_ =~ /Barcode([0-9]*)\t$barcode[$index]\t$otherarray[$index]/) {
                my $bar = $1;
                $_ =~ s/.*//;

                print OUT ">Barcode$bar"."_"."$barcode[$index]\t$otherarray[$index]";
            }
            print OUT $_;
        }
        $index++;
    }
}

好的,我们可以说输入是:

File:
Barcode001    001    abc
Barcode002    002    def
Barcode003    003    ghi

@barcode holds:

001
002
003

@otherarray holds:

abc
def
ghi

此脚本的输出结果当前仅打印:

  

Barcode001_001 abc

应该打印:

>Barcode001_001    abc
>Barcode002_002    def
>Barcode003_003    ghi

应该打印最多约40行的整个负载。

有什么想法吗?我访问数组元素的方式一定有问题吗?还是递增?希望这不是太傻了! 提前谢谢。

它需要索引,因为我试图并行匹配数组,因为它们是有序的。每行需要将数组的相应索引与文件中的每一行匹配。

3 个答案:

答案 0 :(得分:2)

如果没有关于@barcodeFILE内容的更多信息,确实有点难以回答,但是您的代码中有一些奇怪的东西让我觉得它可能是问题

构造while (<FILE>) { ... }将在文件结束之前从FILE读取一行到$_,然后执行循环的内容。在您的代码中,您还可以阅读循环内FILE的所有行,这些行遍历@barcode。我认为您可能打算检查FILE中与@barcode的所有元素相对应的每一行,这将使循环看起来如下所示:

while (my $line = <FILE>) {
    foreach my $barcode (@barcode) {
        if ($line =~ /Barcode([0-9]*)\t$barcode/) {
            my $bar = $1;
            print OUT ">Barcode$bar"."_"."$barcode\n";
        }
        else {
            print OUT $line;
        }
    }
}

我冒昧地做了一些代码整理,但我可能做了一些无根据的假设。

答案 1 :(得分:0)

上面的核心问题是 - 在第一次迭代中,您将文件的所有标记为@lines。但是因为它在词法上限定为循环,所以当循环完成时它会消失。

此外:

  • 我强烈建议你不要那样使用$_

$_是一个隐式设置在循环中的特殊变量。我强烈建议您需要用不是特殊变量的东西替换它,因为这是一种让自己痛苦的可靠方法。

  • 开启use strict;use warnings;

  • 使用3个参数open和一个词法文件句柄。

  • perltidy您的代码,因此包围看起来正确。

  • 您在$_上搜索并替换了完全清空它的模式,但是您正在尝试打印它。您可能无法打印您认为正在打印的内容。

  • 您正在循环外部和内部访问<FILE>。这会给你带来麻烦。

    • Barcode([0-9]*) - 使用'*'表示'零或更多'是有效的。您可能需要考虑\d+ - 一个或多个数字。

    • 通过索引引用多个数组是混乱的。我建议将它们合并到哈希查找中(按键查找 - 条形码)

这一行:

my @line = <FILE>;

将您的整个文件读入@line。但是你在while循环中执行此操作,迭代... <FILE>中的每一行。不要这样做,这太可怕了。

这是你想要的吗?

#!/usr/bin/perl

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

my @barcode = qw (
    001
    002
    003
);

my @otherarray = qw (
    abc
    def
    ghi
);

my %lookup;
@lookup{@barcode} = @otherarray;

print Dumper \%lookup;

#commented because I don't have your source data
#my $file   = "input_file_name";
#my $output = "output_file_name";

#open( my $input,  "<", $file )  or die "\nNot opening $file for reading\n\n";
#open( my $output, ">", $final ) or die "Did not open $final\n";

#while ( my $line = <$input> )
while ( my $line = <DATA> ) {
    foreach my $barcode (@barcode) {
        if ( my ($bar) = ( $line =~ /Barcode(\d+)\s+$barcode/ ) ) {
            print ">Barcode$bar" . "_" . "$barcode $lookup{$barcode}\n";
            #print {$output} ">Barcode$bar" . "_" . "$lookup{$barcode}\n";
        }
    }
}

__DATA__
Barcode001    001
Barcode002    002
Barcode003    003

打印:

$VAR1 = {
          '001' => 'abc',
          '002' => 'def',
          '003' => 'ghi'
        };
>Barcode001_001 abc
>Barcode002_002 def
>Barcode003_003 ghi

答案 2 :(得分:0)

事实证明这是一个简单的问题,因为我怀疑是星期一。我让一位同事和我一起经历了这件事,而且是索引的放置:

#my $index = 0; #This means the index is iterated through, 
                #but for each barcode for one line, then it continues 
                #counting up and misses the other values, therefore 
                #repeatedly printing just the first element of the array.
open(FILE, "$file") or die "\nNot opening $file for reading\n\n";
open(OUT, ">$final") or die "Did not open $final\n";
while (<FILE>) {
    $index = 0; #New placement of $index for initialising.
    foreach my $barcode (@barcode) {
        my @line = <FILE>;
        foreach $_ (@line) {
            if ($_ =~ /Barcode([0-9]*)\t$barcode[$index]\t$otherarray[$index]/) {
                my $bar = $1;
                $_ =~ s/.*//;
            print OUT ">Barcode$bar"."_"."$barcode[$index]\t$otherarray[$index]";
            }
        print OUT $_;
        $index++; #Increment here
        }
    #$index++; 
    }
}

感谢大家的回复,对于我原来的和措辞不好的问题,他们本来可以工作并且可能更有效率,但是出于脚本和编辑问题的目的,它需要这样。