2011-12-05 80 views
3

我正在編寫一個腳本,它從目錄中獲取文件列表,打開每個文件,然後搜索包含帶.zip擴展名的文件的行。然後我想從行中去掉文件名。以下是我的代碼:提取文件名

foreach (@fnames) { 
    chomp ($_); 
    open FILE, '<', "$_"; 
    @archives = grep { /.+?\.zip/ } <FILE>; 

    foreach (@archives) { 
     if ($_ =~ /("|>)(.+?)("|<)/) { push @files, $2; } 
    } 
} 

我從中拉取數據的文件將包含雙引號或尖括號之間的.zip文件名。這段代碼沒有返回,但我知道文件名在那裏。如果我在終端上做了一個grep,我可以看到所有這些,但是Perl中的grep並沒有給我任何東西。有任何想法嗎?

+0

它爲我用一個小的測試腳本。你有沒有試過在第二個循環內拋出'@ archives'和'$ _',以確保你所期望的是事物? – CanSpice

回答

6

可能的事情錯:

  • @fnames是空的,因爲在代碼中的一些錯誤,你是不是 表現。
  • open FILE, ...失敗,但由於您沒有檢查open的返回值 ,因此無法默默無聞,因此您不知道。使用open ... or die $!
  • 您的輸入中有大寫字母,例如: ZIP,並且不要使用 的/i忽略grep中的case選項。順便說一句,.+?在開始 是相當無用的,除非你期望不需要的字符串開始 .zip(即它只檢查至少有一個字符之前)。
  • 第二個循環內的if語句只會抓取第一個 匹配項。

另外:

  • 你應該使用詞法文件句柄與open
  • 如果您尚未這樣做,您應該使用strict和warnings。
  • my @archivesmy @files在適當的詞彙範圍將幫助 保證你得到並保留你想要的數據。
  • $_ =~ /.../可以簡單地寫成/.../以獲得更好的可讀性 (IMO)。
  • 你不(真的)需要一個轉換變量。
  • ("|>)是一種多餘的說法[">]
  • grep是冗餘處理。你可以簡單地做:

while (<FILE>) { 
     push @files, /[">](.*\.zip)["<]/ig; 
} 

簡而言之:

my @files; 
foreach my $file (@fnames) { 
    chomp $file; 
    open my $fh, '<', $file or die $!; 
    while (<$fh>) { 
     push @files, /[">](.*\.zip)["<]/ig; 
    } 
} 
print "File names found: @files\n"; 
+0

這很棒!謝謝您的幫助。我正在使用autodie,這就是爲什麼當我打開文件句柄時不包括死亡。我認爲這個問題(如上所述)是@archives數組沒有被填充。我仍在學習正則表達式,所以我還不熟悉所有的技巧。再次感謝! – stimko68

+0

@ stimko68不客氣! – TLP

0

在你的腳本中,你不輸出任何東西,你只是改變數組中的元素。你必須print你的線路,或使用Tie::File作爲一個數組直接訪問每個文件。