Question

first off thanks for taking the time to look at this.

I'm new to perl, and I struggle with counts in every damn language I learn...guess I was dropped too many times as a kid. I am running a script grepping security logs for failed logins over ssh.

I want to print only the first 25 results from this code, but everything I have tried does not seem to do it (while, for, another foreach) :/, hoping to get some ideas and then facepalm myself. It's also late...yea that's it...that's why I'm dumb

# list each IP ($z) and number of attempts ($count{$z}, sort by highest amount of attempts

foreach $z (sort { $count{$b} <=> $count{$a} } (keys %count) )  {
        @geoData= &getGeo( $z );            # use subroutine getGeo to get location info
        $cityName = $geoData[0];            # extract city from location info
        $countryCode = $geoData[1];         # extract country code from location info
        $reg = $geoData[2];    # extract country code digit
        printf "  %4d    %-20s %-3s %-6s %-20s\n", $count{ $z }, $z, $countryCode, $reg, $cityName;
}

Here's what the output will look like, only it lists hundreds of IP's, I just want 25.

=======================Intrusion Report=======================
  Count   Remote IP Address    Country    City
==============================================================
  7427    182.x.x.x            IN
  4091    200.x.x.x            DO  05     Santo Domingo
  2808    42.x.x.x             CN
  2223    114.x.x.x            CN  23     Shanghai
  1958    122.x.x.x            CN  02     Hangzhou
  1915    202.x.x.x            ID  04     Jakarta
  1410    klinikk.x.x.x        RU  47     Klin
  1190    195.x.x.x            DE  16     Berlin
   805    60.x.x.x             CN  01     Hefei
   646    tango054.x.x.x       DE
   645    216.x.x.x            US  CA     Canyon Country
   645    72.x.x.x             US  CA     Canyon Country
   583    61.x.x.x             CN  02     Wenzhou

Thank you in advance!

Was it helpful?

Solution

Use a list slice to limit the loop to 25 elements:

for my $z ( ( sort { $count{$b} <=> $count{$a} } (keys %count) )[0..24] ) {
  ...
}

A few comments:

  • for is identical to foreach. The two are synonymous.
  • You should use strict; use warnings;. This would require you to lexicalize the scope of the variables declared and used inside the for loop with my.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top