Perl 难以使用全局符号和显式包名称

Perl 难以使用全局符号和显式包名称,perl,Perl,我需要帮助调试下面显示的代码。我问过这个问题的类似版本,但我还没能开发出一个有效的脚本。我的输入文件如下所示: 第1行 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 第2行 bbbbbbbbbbbbbbbbbb 第3行 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

我需要帮助调试下面显示的代码。我问过这个问题的类似版本,但我还没能开发出一个有效的脚本。我的输入文件如下所示:

第1行 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 第2行 bbbbbbbbbbbbbbbbbb 第3行 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 第4行 dddddddddddddddddddd

我希望脚本随机地洗牌文件中的行,例如:

第2行 bbbbbbbbbbbbbbbbbb 第1行 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 第4行 dddddddddddddddddddd 第3行 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

文件中有很多行~1000000。目前,我发现以下错误:

Global symbol "$header_size" requires explicit package name at fasta_corrector9.pl line 40.

我不明白如何给$header\u size一个显式的包名。我不是程序员,所以我需要非常基本的解释。提前谢谢

#! /usr/bin/perl

use strict;
use warnings;

print "Please enter filename (without extension): ";
my $input = <>;
chomp($input);

print "Please enter total no. of sequence in fasta file: ";
my $orig_size = <> * 2 - 1;
chomp($orig_size);

open(INFILE, "$input.fasta") or die "Error opening input file for shuffling!";
open(SHUFFLED, ">" . "$input" . "_shuffled.fasta")
    or die "Error creating shuffled output file!";

my @array  = (0);    # Need to initialise 1st element in array1&2 for the shift function
my @array2 = (0);
my $i      = 1;
my $index  = 0;
my $index2 = 0;

while (my @line = <INFILE>) {
    while ($i <= $orig_size) {

        $array[$i] = $line[$index];
        $array[$i] =~ s/(.)\s/$1/seg;

        $index++;
        $array2[$i] = $line[$index];
        $array2[$i] =~ s/(.)\s/$1/seg;

        $i++;
        $index++;
    }
}

my $array  = shift(@array);
my $array2 = shift(@array2);
for $i (reverse 0 .. $header_size) {
    my $j = int rand($i + 1);
    next if $i == $j;
    @array[$i,  $j] = @array[$j,  $i];
    @array2[$i, $j] = @array2[$j, $i];
}

while ($index2 <= $header_size) {
    print SHUFFLED "$array[$index2]\n";
    print SHUFFLED "$array2[$index2]\n";
    $index2++;
}
close(INFILE);
close(SHUFFLED);

简而言之,您在代码中使用了$header\u size,但没有告诉Perl$header\u size的确切含义。这正是为什么使用严格;强烈建议使用,否则它将在数值上下文中被静默视为未定义的值0

有助于理解此类信息:

全局符号%s需要显式包名

F您说过使用strict或使用strict vars,这表示 所有变量必须使用my或 声明,使用我们的 说出全局变量正在使用的包::


将此应用于手头的问题,$header\u size尚未初始化。在这种情况下要做的事情是分配我的$header\u size=$some\u值;在你使用它之前,或者只是我的$header\u大小;如果您真的不想定义它。

对于这种大小的文件,最简单的方法是允许对数据文件的行进行随机访问

如果文件不存在,使用O_RDWR模式可以防止创建该文件

此外,中的shuffle函数将允许您对原始文件记录的索引进行随机重新排序

use strict;
use warnings;

use Tie::File;
use Fcntl 'O_RDWR';
use List::Util 'shuffle';

tie my @source, 'Tie::File', $ARGV[0], mode => O_RDWR, autochomp => 0
    or die "Unable to open file '$ARGV[0]': $!";

for my $line (shuffle 1 .. @source/2) {
  printf "line %d\n", $line;
  print $source[$line * 2 - 1];
}
此程序应按以下方式运行:

perl shuffle.pl infile > outfile

根据脚本fasta_corrector9.pl的名称和文件的格式,我将假设您正在使用fasta序列进行操作。如果这是真的,我认为您应该真正了解CPAN上的Bio名称空间。拥有这些开放格式规范的全部意义在于,人们编写工具来处理格式,并免费提供给您。在这种情况下,您应该强烈考虑使用FASTA文件作为结构化数据。

my $stream  = Bio::DB::Fasta->new('/path/to/files')->get_PrimarySeq_stream;
while (my $seq = $stream->next_seq) {
     # now you are streaming through your FASTA sequences in order.
     # You can accomplish shuffling with O(1) space complexity in this loop. 
 }

实际上,您希望使用词法my$header\u size;而不是通过显式指定包名$main::header\u size来使用包变量。您也从未给$header\u size赋值。我敢肯定我以前在你的代码中两次提到过这个问题!你的意思是喜欢$i=我的$header\u尺寸$i>=0$我-{这?我被告知这是错误的。我不知道如何给$header_size赋值,或者给$header_size赋值。在for中使用它之前,您需要给它赋值,所以您需要让变量更快地存在,所以您必须更快地声明它。同样,您从不给$header_size赋值,所以您需要我的$header_size=…;在某个地方!!!我如何初始化$header_size?听ikegami!请提问,然后听。我的$header_size=1000;其中1000是你的头大小。老实说,当你从未给这个变量一个值时,你怎么会期望它中有一个值?对于一个有一百万行的文件,Tie::File不是一个内存占用器吗?我从文档中得到了答案:该文件未加载到内存中,因此即使是大型文件也可以使用。这太棒了!它工作得非常好,但有一个问题。我的行是成对的。行1总是与AAA一起,行2总是与BBB一起,等等。此输出不会将行对保持在一起。您能建议一种修改来解决此问题吗?@user1569630:我很抱歉前面!抱歉-我理解您的问题,直到您重新格式化数据并再次更改以显式打印正确的第99行,而不是从file@msonk:嘿,如果您正在学习Perl,那么采用逐段的方式就可以了。@user1569630:第一个改进是使用单个数组,其中每个条目有两行g push@lines,$\uu而$\uu=。比如说。哦,顺便说一句,OP,如果你为了某种科学目的试图一行一行地混合一个FASTA序列,那么你应该被告知你的方法不足以创建一个随机重叠序列,并且你根据这样的假设所做的任何分析都被污染了。事实上,FASTA序列是分为多行是一个实现细节。+1假设这个Fasta模块是适合输入的模块,我不知道,这个解决方案更可取,也许应该是可以接受的答案。
my $stream  = Bio::DB::Fasta->new('/path/to/files')->get_PrimarySeq_stream;
while (my $seq = $stream->next_seq) {
     # now you are streaming through your FASTA sequences in order.
     # You can accomplish shuffling with O(1) space complexity in this loop. 
 }