2013-12-23 63 views
1

我有文件名,如lin.txt和lin1.txt以及其他.txt文件。我只需要找到這些文件並只打印一個內容。我有下面的代碼,但它以某種方式不匹配以lin *開頭的文件。什麼是問題?在if條件下匹配文件名perl

$te_dir= "/projects/xxx/"; 
opendir (DIR, $te_dir) or die $!; 
while (my $file = readdir(DIR)) 
{ 
       if ($file=~/\.txt/) 
       { 
      #// Doing some tasks. 

      if($file ~= 'lin*.txt') 
      { 
       $linfile=$te_dir/$file; 
       open(LINFILE, $linfile) or die "Couldn't open file $file:$!"; 
       while(my $line = <LINFILE>) 
       { 
       print $line; 
       } 
       close LINFILE;  

      } 

     } 

} 

回答

3

您正在將globs(shell通配符)與正則表達式混合使用。這是具有不同語法和語義的兩種不同形式。在正則表達式中(這是Perl匹配的用途),n*匹配零個或多個出現的字符n。您可能的意思是

if ($file =~ /lin.*\.txt/) 

注意運算符中的語法錯誤。您在第一個條件中正確地有=~,但是您將其拼寫爲~=,您在此處進行此比較。 (也許它只是一個抄寫錯誤。對我來說,這創造了一個清晰的語法錯誤,所以腳本不會首先運行)

正如@brianadams的回答指出,這樣做的正確的正則表達式

if ($file =~ /^lin.*\.txt$/) 

與行首^和行尾$錨以防止例如feline.txt.html從匹配。 Perl正則表達式的默認行爲是在輸入字符串中的任意位置查找匹配項。

+1

'$ te_dir/$ file'周圍還有(雙)引號,但這也可能是一個轉錄問題。 –

1

要匹配開頭的文件lin

if ($file =~ /^lin.*\.txt$/) 
1

這是你的代碼的快速(和最小)重寫,這可能有助於:

use strict; 
use warnings; 

my $te_dir = "/projects/xxx/"; 
opendir(my $dirh, $te_dir) or die "Could not open '$te_dir': $!"; 

while (my $file = readdir($dirh)) { 
    next unless $file =~ /\.txt$/; 

    #// Doing some tasks. 
    if ($file =~ /^ lin \d* \.txt $/x) { 
     my $linfile = "$te_dir/$file"; 
     open(my $fh, $linfile) or die "Couldn't open file $linfile: $!"; 
     while (my $line = <$fh>) { 
      print $line; 
     } 
     close $fh or die "Could not close $linfile: $!"; 
    } 
} 

首先,請注意,我們已經把strictwarnings在代碼的頂部。這會告訴你各種有趣的問題,包括拼寫錯誤的變量名稱。

接下來,我們切換到詞法句柄(例如,my $dirh而不是DIR)。您正在使用的手柄的「裸號」版本(DIRLINFILE)長期以來一直受到阻礙,因爲這些手柄實際上是全球性構造,而且通常全球數據不好,因爲當它被破壞時,很難分辨出它是什麼,所以我們非常非常喜歡的詞彙版本(與my內置宣佈手柄)

而且,這條線,你可能有不這樣做,你在想什麼:

$linfile=$te_dir/$file; 

你試圖用正斜槓將目錄和文件名一起粉碎,但由於您沒有使用字符串插值,所以實際上使用的是。在這個數字上下文中,您的導演和文件名都可能評估爲零,當您嘗試打開文件時,會給您一個零除錯誤!

但是,如果你願意使用CPAN模塊,您可以更輕鬆地進行:

use strict; 
use warnings; 

use File::Find::Rule; 
my $te_dir = "/projects/xxx/"; 
my @files = File::Find::Rule->file->name('lin*.txt')->in($te_dir); 

foreach my $linfile (@files) { 

    #// Doing some tasks. 
    open my $fh, $linfile or die "Couldn't open file $linfile: $!";                          
    while (my $line = <$fh>) { 
     print $line; 
    } 
} 

沒有搞亂,沒什麼大驚小怪的。在第一遍中只獲取想要的文件,並且已經具有正確的文件名(注意,我沒有關閉文件句柄,因爲$fhforeach循環結束時超出範圍時會自動關閉。)

0

嘗試改變這從你的第二if條件,

if($file ~= 'lin*.txt')

此,

if($file =~ /lin*\.txt/)

您也可以嘗試:if($file =~ /^lin*\.txt/),正如其他答案中已經指出的那樣,但您需要確保存儲在$file變量中的文件名僅包含文件名,而不包含整個路徑。