-3

以下に示すコードのデバッグについて助けが必要です。この質問の同様のバージョンを尋ねましたが、機能するスクリプトを開発できませんでした。私の入力ファイルは次のようなものです:

line1
AAAAAAAAAAAAAAA
line2
BBBBBBBBBBBBBBBB
line3
CCCCCCCCCCCCCCC
line4
DDDDDDDDDDDDDDD

次のように、スクリプトでファイル内の行をランダムにシャッフルしたいと思います。


ライン 2 BBBBBBBBBBBBBBBライン 1 AAAAAAAAAAAAAAA ライン 4 DDDDDDDDDDDDDDD ライン 3
CCCCCCCCCCCCCCC




ファイルにはかなりの数の行 (~1,000,000) が含まれています。現在、次のエラーが発生します。

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

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

$header_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);
4

3 に答える 3

3

そのサイズのファイルでこれを行う最も簡単な方法Tie::Fileは、データファイルの行へのランダムアクセスを許可するために使用することです

のモードを使用するとO_RDWR、ファイルが存在しない場合にファイルが作成されなくなります

さらに、shuffle関数 fromList::Utilを使用すると、元のファイル レコードのインデックスをランダムに並べ替えることができます。

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
于 2012-09-19T17:49:13.430 に答える
3

一言で言えば、あなたはコードで を使用$header_sizeしていますが、正確に何が何であるかを Perl に伝えていません $header_sizeuse strict;強く推奨されるのはまさにこのためです。そうしないと、未定義の値 (数値コンテキストでは 0) として黙って扱われてしまいます。

perldoc perldiagそのようなメッセージを理解するのに役立ちます:

グローバル シンボル "%s" には明示的なパッケージ名が必要です

(F) " use strict" または " " と言いました。これは、すべての変数が (" " または " "use strict varsを使用して) レキシカルにスコープされているか、 " " を使用して事前に宣言されているか、グローバル変数がどのパッケージに含まれているかを示すために明示的に修飾されている必要があることを示しています。 (「」を使用)。mystateour::

これを当面の問題に適用すると、$header_size初期化されていません。この場合にすべきことは、my $header_size = $some_value;使用する前に代入するか、単にmy $header_size;未定義のままにしたい場合です。

于 2012-09-19T17:44:14.103 に答える
2

スクリプトの名前(fasta_corrector9.pl)とファイルの形式に基づいて、FASTAシーケンスで何かをしていると仮定します。それが本当なら、CPANのBio名前空間を本当に理解する必要があると思います。これらのオープンフォーマット仕様を持つことの全体的なポイントは、人々がフォーマットを操作して無料であなたにそれらを与えるためのツールを書くことです。この場合、Bio :: DB :: Fastaを使用して、構造化データとして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. 
 }
于 2012-09-19T17:50:51.323 に答える