2016-02-18 69 views
1

我是perl的新手。我有一個目錄結構。在每個目錄中,我都有一個日誌文件。我想從該文件中grep模式並進行後期處理。現在我使用unix grep從這些文件中選擇模式並將其放入文本文件中,然後讀取該文本文件以進行後期處理,但是我想要自動執行從該文件讀取每個文件和grepping模式的任務。在下面的代碼mdp_cgdis_1102.txt已從目錄grepped模式。我真的很感激任何幫助perl中的遞歸grep

#!usr/bin/perl 

use strict; 
use warnings; 

open FILE, 'mdp_cgdis_1102.txt' or die "Cannot open file $!"; 

my @array = <FILE>; 
my @arr; 
my @brr; 

foreach my $i (@array){ 
@arr = split (/\//, $i); 
@brr = split (/\:/, $i); 
print " $arr[0] --- $brr[2]"; 
} 
+5

你可以顯示一個示例目錄結構和你想grep的字符串的例子嗎? – choroba

+0

可能是'File :: Find'的工作。很難說沒有更多的信息你在做什麼。 – Sobrique

+0

因此,文本文件具有unix grep的輸出,並且您想要使用該輸出? – bolav

回答

0

這是我不清楚這過程的一部分需要自動化。我會通過「」想要自動從文件中讀取每個文件和grepping模式,「據此您大概已經有了一個文件列表。如果您確實需要構建文件列表以及下面添加的代碼。

一種方式:從每個文件把所有的模式和存儲在一個散(filename->陣列REF-用圖案)

my %file_pattern; 
foreach my $file (@filelist) { 
    open my $fh, '<', $file or die "Can't open $file: $!"; 
    $file_pattern{$file} = [ grep { /$pattern/ } <$fh> ]; 
    close $fh; 
} 

[ ]需要參照由grep返回的列表,即。構造一個「匿名數組」,並且該(引用)被賦值爲「文件」鍵值。

現在你可以處理你的模式,每個日誌文件

foreach my $filename (sort keys %file_pattern) { 
    print "Processing log $filename.\n"; 
    my @patterns = @{$file_pattern{$filename}}; 
    # Process the list of patterns in this log file 
} 


ADDED

爲了建造上面使用,從目錄中的一個已知列表文件@filelist的列表中,使用核心File::Find 遞歸掃描提供的目錄並應用提供的子程序的模塊

use File::Find; 
find({ wanted => \&process_logs, preprocess => \&select_logs }, @dir_list); 

將子例程process_logs()應用於找到的每個文件/目錄,並且可以使用上述的每個日誌模式填充散列,或者可以根據需要運行完整處理;您可以在模塊的$File::Find::name下提供一個文件,以便隨您使用。您的子程序select_logs()將包含代碼,用於過濾來自每個目錄中所有文件的日誌文件,即File::Find正常進程,以便process_file()僅獲取日誌文件。另一種方法是使用其他調用

find(\&process_all, @dir_list); 

現在在哪裏子process_all()應用於找到的所有文件,因此需要確保自身,它僅處理日誌文件。查看鏈接的文檔。

0

使用File::Find遍歷目錄。

在循環遍歷所有的日誌文件:

  1. 打開文件
  2. 讀它一行行
  3. 對於每一行,做一個正則表達式匹配( if ($line =~ /pattern/)),或使用 if (index($line, $searchterm) >= 0)如果你正在尋找一個特定的靜態字符串。
  4. 如果找到匹配項,請打印該行。
  5. 關閉文件

我希望給你足夠的指針開始。如果你自己發現如何在Perl中完成這些步驟,你將學到更多東西(我指出了困難)。

1

find ... -name '*.txt' -type f -exec grep ... {} + 

相當於是

use File::Find::Rule qw(); 

my $base_dir_qfn = ...; 
my $re = qr/.../; 

my @log_qfns = 
    File::Find::Rule 
    ->name(qr/\..txt\z/) 
    ->file 
    ->in($base_dir_qfn); 

my $success = 1; 
for my $log_qfn (@log_qfns) { 
    open(my $fh, '<', $log_qfn) 
     or do { 
     $success = 0; 
     warn("Can't open log file \"$log_qfn\": $!\n); 
     next; 
     }; 

    while (<$fh>) { 
     print if /$re/; 
    } 
} 

exit(1) if !$success;