2014-02-18 86 views
1

我正在寫一個模式匹配的程序在perl中。但是出現錯誤..我已經看到關於此事的所有早期帖子,但是沒有找到解決方案...由於我是新來perl的所以我沒有得到什麼這個錯誤是一回事..

use of uninitialized value $line in string ne at line .. and in line ... 

我在這裏附上一個Perl文件

use strict; 

use warnings; 

my $line = ""; 

open(OUTFILE, ">output.txt") or die ("cannot open file.\n"); 

if(open(file1,"match.txt") or die "Cannot open file.\n"){ 
    $line = <file1>; 

    while ($line ne "") { 
    if (defined($line) && (line =~ m/\sregion\s/i)) { 
     print OUTFILE ("$line")}; 
     $line = <file1>; # Problem Here 
     if (defined($line) && ($line =~ /\svth\s/)) { 
      print OUTFILE ("$line") 
      }; 

     $line = <file1>; # Problem Here 
    } 
} 

我match.txt文件包含此類資料..

Some text here 

    region  Saturati Saturati  Linear Saturati Saturati 

    id  -2.1741m -2.1741m -4.3482m 2.1741m 2.1741m 

    vth  -353.9140m -353.9141m -379.2704m 419.8747m 419.8745m 

Some text here 

請解決問題....感謝

+0

你可以在'open(...)或'...''周圍丟失'if(...)'。 –

+0

在while循環後面有一個空字符「line」,並且您還應該使用open的3參數形式。此外,你應該使用file1文件句柄,而不是 – chilemagic

+0

'grep「\ b(region | vth)\ b」match.txt' – TLP

回答

0

從外觀上來看,好像你試圖去通過匹配的文件和打印所有符合regionvthoutput.txt的行。

我簡化了代碼,你這樣做:

use strict; 
use warnings; 

open(my $out_fh, ">", "output.txt") || die ("Cannot open file.\n"); 
open(my $file1, "<", "match.txt") || die ("Cannot open file.\n"); 

while(<$file1>) { 
    if (/\s(region|vth)\s/i) { 
     print $out_fh $_; 
    } 
} 

這個問題進入更詳細的關於檢查變量是否被定義或爲空:In Perl, how can I concisely check if a $variable is defined and contains a non zero length string?

下面是關於打開文件的詳細信息: What's the best way to open and read a file in Perl?

+0

這一個正在工作..謝謝...但我想知道什麼是錯誤我的代碼... – user3318901

+0

嘿馬特我也想知道$ _在打印行 – user3318901

+0

的意思嘿! 'while(<$file1>)'將遍歷文件中的每一行,而在while循環中,'$ _'將是該行的值。它基本上取代你的變量'$ line'。如果你想用變量'$ line'代替,你也可以使用'while(my $ line = <$file1>)'。 – chilemagic

1

如果你什麼都看不懂,你的字符串會回來undefined ...這就是爲什麼你看到這條消息。

而且,可能更好地檢查你打開輸入文件首先創建一個輸出文件可言,所以這樣的事情之前:

open(INFILE, "<match.txt") or die "Cannot open input file"; 
open(OUTFILE, ">output.txt") or die "cannot open output file"; 

my $line; 
while($line = <INFILE>){ 
    ... 
} 

Perl會結束循環,如果$線是未定義或空字符串。

+0

看到這打開一個文件:http://stackoverflow.com/questions/318789/whats-the-best-way-to-open-and-read-a-file-in-perl – chilemagic

+0

你不能'while( $ line)'',你需要'while($ line = )'。另外,你打開'INFILE',但是從'file1'讀取。你的die語句應該包含錯誤'$!',並且'open'應該是帶有詞法文件句柄的三個參數'open my $ fh,「<」,$ file或者「不能打開:$!」; – TLP

1

您看到這些錯誤的原因是變量$line包含undef。它包含undef的原因是,在文件到達末尾eof後,您爲其分配了一個值readline()<file1>)。這在perldoc -f readline描述:

在標量環境中,每個 呼叫讀取並返回下一行 直到達到結束文件,於是後續呼叫返回「是undef」。

您遇到此錯誤的原因是您沒有使用傳統方法讀取文件。通常情況下,你會做這個讀取文件:

while (<$fh>) { 
    ... 
} 

,直到它到達文件結束這將在遍歷文件中的所有行,在這之後,你現在知道了,readline回報undef和同時循環退出。

這也意味着您不必檢查每隔一行是否定義了$line或爲空。此外,你可以在你的正則表達式組合成一個,並通常會刪除大量的冗餘代碼:

while (<>) { 
    if (/\b(?:region|vth)\b/i) { 
     print; 
    } 
} 

這是你所追求的功能核心,我使用一些Perl的成語這裏:鑽石操作<>將從您給腳本作爲參數的文件名中讀取,如果沒有給出參數,則從STDIN中讀取。如果沒有給出任何參數,許多內置函數使用$_變量作爲默認值,這是print的作用,以及while循環條件。

您也可能會注意到,我用字邊界\b,而不是空白\s在正則表達式,並使用交替|與非捕獲括號(?:...),這意味着它可以匹配這些字符串之一。

有了這個簡單的腳本,你可以這樣做:

perl script.pl match.txt > output.txt 

要爲您的文件名。