2013-12-09 33 views
2

我有一个TCPDUMP文件,其中包含许多单词USER和PASS的用法,我需要制定一个正则表达式来查找它们,然后打印每个文件的数量。 (或任何不同的方式;正则表达式是我对这些问题的第一选择)。我认为我的分裂似乎并不正确。不知道我在这里做错了,所以有什么想法?提前致谢!使用正则表达式找到一个匹配 - perl

下面是输入文件的例子(注意:这仅仅是2006行的文件的第一行的格式是相同的,但数字,符号,和字母DO中的每一行改变)

22:28:28.374595 IP 98.114.205.102.1821 > 192.150.11.111.445: Flags [S], seq 147554406, win 64240, options [mss 1460,nop,nop,sackOK], length 0E...<[email protected] ...\.bfP....Y..echo open 0.0.0.0 8884 > USER 1 1 >> 

代码:

#!/usr/bin/perl -w 
use strict; 
use warnings; 
use diagnostics; 

#opens txt file: read mode 
open MYFILE, '<', 'source_file.txt' or die $!; 

#opens output txt file: write mode 
open OUT, '>', 'Summary_Report.txt' or die $!; 

#open output txt file: write mode 
#used to store header 'split' info 
open OUTFILE, '>', 'Header.txt' or die $!; 

my $start_time = undef; 
my $end_time; 
my $linenum = 0; 
my $user; 
my $pass; 

while (<MYFILE>) { 
    chomp; 
    $linenum++; 
    #print ": $_\n"; ###if I need to see the lines (check)### 

    #separate pieces of information from TCPDUMP into list 
    my @header = split (' ',$_); 
    print OUTFILE "$linenum: @header\n\n"; 

    if (/^22:28/ && !defined($start_time)) { 
     $start_time = $header[0]; 
     #print "$start_time\n"; ###used as a check### 
    } 

    if ($_ = /22:28/) { 
     $end_time = $header[0]; 
    }  

    if ($_ =~ m/USER/i) { 
     $user = $header[10]; 
    } 

    } 

print OUT "Total # of times phrases were used:\n\n 
USER (variations thereof) = $user\n\n 
PASS (variations thereof) = $pass\n\n\n"; 
+0

请发布您的输入外观。 – hwnd

+0

希望我所做的帮助呀。 – user2288

+0

我刚刚意识到我需要一些元字符,这些可能会有所帮助!不太确定如何去解决它们。 – user2288

回答

1
my @lines = (<MYFILE>); 
my @matches = grep { $_ =~ /(PASS|USER)/i } @lines; 

该工作吗?

加上行号:

my @lines = (<MYFILE>); 
my %results; 
map { 
    if ($lines[$_] =~ /(pass|user)/i) { 
     $results{$_} = $lines[$_]; 
    } 
} 0..$#lines; 

%的结果将有钥匙的行号,价值线。因为它的递归,Grep更快,这将是O(n2)iirc。

现在..

map { 

    #separate pieces of information from TCPDUMP into list 
    my @header = split (' ',$results[$_]); 
    print OUTFILE "$_: @header\n\n"; 

    if (/^22:28/ && !defined($start_time)) { 
    $start_time = $header[0]; 
    #print "$start_time\n"; ###used as a check### 
    } 

    if ($results[$_] = /22:28/) { 
    $end_time = $header[0]; 
    }  

    if ($results[$_] =~ m/USER/i) { 
     $user = $header[10]; 
    } 

} keys %results; 
+0

实际上我的工作确实奏效了,但它最终重置了我的$亚麻布变量和我的时间变量,但不幸我不能发生 – user2288

+0

您可以推到行号的索引给我一个秒.. –

1

我真的不知道perl的,但我知道正则表达式...,你可以用这句话来匹配22.28开头的所有行其中还包含USER/PASS:

(?<=22\.28)USER|PASS 

我不是100%清楚你需要什么,如果你进一步指定,我可以帮忙。

+0

我真正想做的就是使用正则表达式函数来查找位于我的输入文件中的单词PASS&USER的所有实例。我知道答案很简单,但出于某种原因,无论我做什么都行不通,那对我有帮助吗? – user2288

+0

你可以使用下面的Perl代码使用字符串中的匹配来创建一个数组:'@result = $ input =〜m/USER | PASS/ig;'......不知何故,我认为你并不是追求这么简单的东西。 –

1

这里有一个USER/PASS计数选项:

use strict; 
use warnings; 

my %user_pass; 

while (<DATA>) { 
    $user_pass{$1}++ while /(\bUSER\b|\bPASS\b)/g; 
} 

print "$_ => $user_pass{$_}\n" for keys %user_pass; 

__DATA__ 
USER USER PASS PASS 
PASS 
USER 
USER 
PASS PASS 

输出:

PASS => 5 
USER => 4 

希望这有助于!