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;
}
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;
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;
}
精彩评论