2014-10-07 86 views
1

我正在使用一個文件(TARGET)的行來查看它們是否在另一個文件(CHECK)中。它適用於TARGET文件在第一行中有匹配的情況,但不在其他任何地方。它看起來像第一個while循環只是檢查TARGET的第一行,而不是所有的行。我如何使它實際檢查文件的所有行?Perl While循環僅檢查文件的第一行

while (my $line = <TARGET>) { 
    chomp($line); 
    while (my $check = <CHECK>) { 
     if ($check =~ $line) { 
      print "Found a match: $check"; 
     } 
    } 
} 

謝謝。

+0

可能重複的[比較文件中的行與Perl](http://stackoverflow.com/questions/5260450/comparing-lines-in-a-file-with-perl) – ThisSuitIsBlackNot 2014-10-07 19:45:39

+0

您可以發佈一些'TARGET'的示例輸入和'CHECK'? – 2014-10-07 19:46:31

+0

如果你正在製作一個完整的Perl腳本來比較文件內的行,我建議使用'comm'命令。它完全符合你的要求。 https://stackoverflow.com/questions/373810/unix-command-to-find-lines-common-in-two-files – 2014-10-07 20:07:15

回答

3

您掃描整個CHECK文件句柄爲目標的第一線,那麼有沒有更多的線路。如果您想以這種方式處理任務,則需要倒帶或重新打開每行TARGET的CHECK。

2

你的代碼有一些錯誤。

  1. $check =~ $line通過使用$line作爲正則表達式比較兩者。您應該使用字符串comparison operators來比較它們:$check eq $line
  2. chomp($line)但從來沒有chomp($check)。這意味着$check將始終具有尾隨換行符。
  3. 從文件中讀取行會移動文件指針,這意味着在完成內部while循環後,CHECK將保留在文件結尾處。爲防止出現這種情況,請在循環前將數據加載到數組中。

請嘗試以下,看看它的工作原理:

chomp(my @lines = <TARGET>); 
chomp(my @checks = <CHECK>); 

for my $line (@lines) { 
    for my $check (@checks) { 
     if ($line eq $check) { 
      print "Found match: $check" . $/; 
     } 
    } 
} 
+0

這仍然會比較'CHECK'對應的文件的每一行,只有* first *對應於'TARGET'的文件行。您必須在外循環的每次迭代中「尋找」第二個文件的開頭,以實際比較一個文件中的每一行與另一個文件中的每一行。不用說,這將是非常低效的。 – ThisSuitIsBlackNot 2014-10-07 19:55:06

+0

更新並修復。 – 2014-10-07 20:05:40

+1

更好的方法(假設第一個文件適合內存)將第一個文件讀入散列,然後逐行檢查第二個文件,檢查每行是否在散列中。 – ThisSuitIsBlackNot 2014-10-07 20:09:27

1

你有兩個問題:

  1. 你只是從你的檢查文件讀取一個時間,然後它停留在eof

  2. 你使用正則表達式比較=~,而不是字符串比較eq

我建議您加載文件檢查到一個哈希,然後遍歷您的其他文件:

my %check = map { $_ => 1 } <CHECK>; 

while (<TARGET>) { 
    if ($check{$_}) { 
     print "Found a match: $_"; 
    } 
}