kingbp
kingbp

Reputation: 1

while loop align columns

hi I wrote a perl script where I stored columns from a text file filled with ip and port scans into variables. The variables contain many ip addreses, ports, protocols, states, and services now I need a while loop that takes all the ip's stored in the ip variable and matches them with its corresponding ports protocols and state etc.side by side look so: 192.168.3 45 tcp open smtp

heres my code

$ip_address = `cat /cygdrive/c/Windows/System32/test11.txt | 
    grep 'Nmap scan report for'`;

$state = `cat /cygdrive/c/Windows/System32/test11.txt | grep -v 'PORT'|
    grep -v 'filtered'| grep -v 'latency'| grep -v 'Nmap' | grep -v 'Discovered' |
    grep -v 'Raw' | grep -v 'SYN' | grep -v 'DNS'| grep -v 'Ping' | 
    grep -v 'Scanning' `;

$port = `cat /cygdrive/c/Windows/System32/test11.txt | grep -v  'Discovered'| 
    grep -v 'Nmap' | grep -v 'PORT' | grep -v 'ports'| grep -v 'Read' | 
    grep -v 'Raw'| grep -v 'Completed'| grep -v 'DNS' | grep -v 'hosts' | 
    grep -v 'Ping' | grep -v 'SYN' | grep -v 'latency' `;

$protocol = `cat /cygdrive/c/Windows/System32/test11.txt | grep -v  'Discovered'| 
    grep -v 'Nmap' | grep -v 'PORT' | grep -v 'ports'| grep -v 'Read' | 
    grep -v 'Raw' | grep -v 'Completed'| grep -v 'DNS' | grep -v 'hosts' | 
    grep -v 'Ping' | grep -v 'SYN' | grep -v 'latency' `;
{

$service = `cat /cygdrive/c/Windows/System32/test11.txt | grep -v 'Nmap' | 
    grep-v 'Host' | grep -v 'filtered' | grep -v 'PORT' | grep -v 'Raw'| 
    grep -v 'Scanning'| grep -v 'Completed'| grep -v 'Ping' |grep -v 'DNS' | 
    grep -v 'Discovered'| grep -v 'SYN'`;

while($ip_address, $port, $protocol, $state, #service)
{
    chomp ($ip_address, $port, $protocol, $state, #service);
    print "$ip_address, $port, $protocol, $state, #service";
    exit 0;
}

Upvotes: 0

Views: 311

Answers (2)

kshep
kshep

Reputation: 499

I usually try to do these sorts of things in one pass, like...

#!/usr/bin/perl

open(F, "/cygdrive/c/Windows/System32/test11.txt");

while(<F>) {

  # If the current line has something that matches an IP
  # address, store the matched pattern in $ip. We'll
  # use this as we process the remaining lines.
  #
  $ip = $1 if ( /Nmap scan report for (\d+\.\d+\.\d+\.\d+)/ );

  # Try to match lines like "ddd/www www www wwww"
  #
  ( $port, $protocol, $state, $service) = ( m|(\d+)/(\w+)\s+(\w+)\s+(\w+)| );

  print "$ip, $port, $protocol, $state, $service\n" if $port;

}

Upvotes: 1

mob
mob

Reputation: 118595

Usually I say to use the tools that you understand and that it's OK to do things like call awk from Perl. But for this code I'll make an exception. You should be using the builtin Perl commands for this task. Namely, arrays and Perl's grep operator. Here's how I would start to rewrite this.

# do this once instead of `cat ...` several times.
open my $fh, '<', '/cygdrive/c/Windows/System32/test11.txt';
my @the_input = <$fh>;
close $fh;

# do this instead of `| grep -v ... | grep -v ...`
my @ip_addresses = grep { /Nmap scan report for/ } @the_input;
my @states = grep { 
    !/PORT|filtered|latency|Nmap|Discovered|Raw|SYN|DNS|Ping|Scanning/
} @the_input;
my @ports = grep {
    !/Discovered|Nmap|PORT|ports|Read|Raw|Completed|DNS|hosts|Ping|SYN|latency/
} @the_input;
my @protocols = grep {
    !/Discovered|Nmap|PORT|ports|Read|Raw|Completed|DNS|hosts|Ping|SYN|latency/
} @the_input;
my @services = grep {
    !/Nmap|Host|filtered|PORT|Raw|Scanning|Completed|Ping|DNS|Discovered|SYN/
} @the_input;

Upvotes: 1

Related Questions