2012-09-19 27 views
-3

我需要幫助調試下面顯示的代碼。我已經問過這個問題的類似版本,但我還沒有能夠開發一個可行的腳本。我的輸入文件是這樣的:全局符號和明確包名難以解決

一號線
AAAAAAAAAAAAAAA
2號線
BBBBBBBBBBBBBBB
3號線
CCCCCCCCCCCCCCC
4號線
DDDDDDDDDDDDDDD

我想腳本隨機洗牌文件中的行,如:

2號線
BBBBBBBBBBBBBBB
一號線
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); 
+2

你竟然想用一個詞彙('我的$ header_size;'),而不是通過明確其包名('$主:: header_size')使用一個包變量。你從來沒有給'$ header_size'一個值。 (我敢肯定,我已經在你的代碼中提到過這個問題了兩次!) – ikegami

+0

你的意思是like(for($ i = my $ header_size; $ i> = 0; $ i--){)this?我被告知這是不正確的。我不知道如何給一個值(或給出什麼值)給$ header_size – user1569630

+2

你需要給它賦值,然後在'for'中使用它,所以你需要這個變量早點存在,所以你必須儘早申報。再說一次,你永遠不會把一個值分配給'$ header_size',所以你需要'我的$ header_size = ...;'某處! – ikegami

回答

2

簡單地說,你在你的代碼中使用$header_size,但沒有告訴Perl的什麼$header_size到底是。這正是爲什麼use strict;高度建議,否則它會被默默地視爲一個未定義的值(0在數字上下文中)。

perldoc perldiag理解這些消息是有用的:

全球符號 「%s」 需要明確的包名

(F)你說: 「use strict」 或 「use strict vars」,這指示 所有變量都必須是詞法範圍的(使用「my」或 「state」),事先使用「our」聲明或明確限定爲 說明全局變量在哪個包中(使用「::」)。

將此應用於手頭的問題,$header_size尚未初始化。在這種情況下要做的事情是在你使用它之前分配my $header_size = $some_value;,或者如果你真的想讓它不確定,就簡單地使用my $header_size;

+0

如何初始化$ header_size? – user1569630

+0

聽ikegami!請提問,然後聽。 '我的$ header_size = 1000;''1000'是你的標題大小。坦率地說,當你從未給過這個變量時,你如何期待這個變量有價值? –

3

與大小的文件,要做到這一點,最簡單的方法是使用Tie::File以允許對數據文件

使用的O_RDWR模式的線隨機存取防止這個文件,如果它不」創建牛逼存在

另外,從List::Utilshuffle功能可以讓你隨機重新排序的原始文件記錄

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]; 
} 

這個節目S的索引HOULD運行爲

perl shuffle.pl infile > outfile 
+0

對於有一百萬行的文件,'Tie :: File'是不是一個內存宏? – Zaid

+0

我從文檔中得到了我的答案:''文件沒有加載到內存中,所以即使對於巨大的文件也是如此。「 – Zaid

+0

固定在源數據中對線對工作 – Borodin

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. 
} 
+0

@msonk:嘿,如果你正在學習Perl,那麼這種零碎的方式很好。 (@ user1569630:首先改進是使用單個數組,每個條目的長度爲兩行('push @lines,$ _ while $ _ = <>。<>'say)) – bobbogo

+0

哦,順便說一下, OP,如果您試圖爲了科學目的而逐行混合使用FASTA序列,那麼您應該知道您的方法不足以創建一系列隨機重疊羣,並且您根據這種假設做的任何分析都受到了污染。 FASTA序列在多行上分解的事實是一個實現細節。 – masonk

+0

+1假設這個Fasta模塊對於輸入是合適的(我不知道),這個解決方案是可取的,也許應該是被接受的答案。 – TLP