使用regex - perl查找匹配

时间:2022-04-08 04:22:24

I have a TCPDUMP file that contains many uses of the word USER and PASS and I need to work out a regex for finding them all and then printing how many there are for each. (or any different way; regex is my first choice for these problems though). And my split seems to not be working right I think. Not sure how I am doing this wrong here so any ideas? Thanks in advance!

我有一个TCPDUMP文件,它包含了用户和PASS的很多用法,我需要找到一个regex来查找它们,然后打印出每一个的数量。(或任何方式不同;regex是我解决这些问题的首选)。我觉得我的分裂似乎不太正常。不知道我怎么做错了,有什么想法吗?提前谢谢!

Here is an example of the input file (note: this is just the first line of the file of 2006 lines. The format is identical, but the numbers, symbols, and letters DO change in each line)

这里有一个输入文件的例子(注意:这只是2006年文件的第一行。格式是相同的,但是数字、符号和字母在每一行都有变化。

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...<.@.q...br.f...o.... ...\.bfP....Y..echo open 0.0.0.0 8884 > USER 1 1 >>

code:

代码:

#!/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";

3 个解决方案

#1


1  

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

Should work?

应该工作吗?

With Line Numbers:

行号:

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

%results will have keys as line numbers, value is line. Grep is faster because its recursive though, this will be O(n2) iirc.

%结果将具有作为行号的键,值为行。Grep更快,因为它是递归的,这是O(n2) iirc。

Now..

现在. .

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;

#2


1  

I don't really know perl, but I know regex... and you could use this expression to match any line beginning with 22.28 which also contains USER/PASS:

我不太懂perl,但我知道regex…您可以使用这个表达式来匹配从22.28开始的任何行,其中也包含用户/PASS:

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

I'm not 100% clear on what you need, if you specify further, I can probably help.

我不是百分之百的清楚你需要什么,如果你进一步说明,我可能会帮助你。

#3


1  

Here's a USER/PASS counting option:

这里有一个用户/密码计数选项:

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

Output:

输出:

PASS => 5
USER => 4

Hope this helps!

希望这可以帮助!

#1


1  

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

Should work?

应该工作吗?

With Line Numbers:

行号:

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

%results will have keys as line numbers, value is line. Grep is faster because its recursive though, this will be O(n2) iirc.

%结果将具有作为行号的键,值为行。Grep更快,因为它是递归的,这是O(n2) iirc。

Now..

现在. .

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;

#2


1  

I don't really know perl, but I know regex... and you could use this expression to match any line beginning with 22.28 which also contains USER/PASS:

我不太懂perl,但我知道regex…您可以使用这个表达式来匹配从22.28开始的任何行,其中也包含用户/PASS:

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

I'm not 100% clear on what you need, if you specify further, I can probably help.

我不是百分之百的清楚你需要什么,如果你进一步说明,我可能会帮助你。

#3


1  

Here's a USER/PASS counting option:

这里有一个用户/密码计数选项:

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

Output:

输出:

PASS => 5
USER => 4

Hope this helps!

希望这可以帮助!