kathys39 has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to parse thru an array, specifically one with nmap's argument list. I am trying to get a list of ports from this line, and having some problems. Here is the code I have:
$args = "nmap -sS -iL ips.txt -p 1-1024 172.27.1.4"; @list = split(/\ /, $args); foreach $list (@servicelist) { if ($list =~/-p/) { ......
what I want to do is advance to the next element and assign that value (in this case 1-1024) to a variable...

Replies are listed 'Best First'.
Re: find element in array, then advance to next element
by toolic (Bishop) on Dec 09, 2008 at 17:56 UTC
    I think Getopt::Long might be able to help. It can stuff all arguments into a hash variable:
    use strict; use warnings; use Data::Dumper; use Getopt::Long; my $args = 'nmap -sS -iL ips.txt -p 1-1024 172.27.1.4'; @ARGV = split /\s+/, $args; my %opt; GetOptions(\%opt, 'sS', 'iL=s', 'p=s'); print 'opt hash ', Dumper(\%opt); print 'ARGV ', Dumper(\@ARGV); __END__ opt hash $VAR1 = { 'sS' => 1, 'p' => '1-1024', 'iL' => 'ips.txt' }; ARGV $VAR1 = [ 'nmap', '172.27.1.4' ];

    Update: related node: search array for item, move to next item

Re: find element in array, then advance to next element
by ikegami (Patriarch) on Dec 09, 2008 at 17:49 UTC
    my ($idx) = grep $list[$_] eq '-p', 0..$#list; or die("-p not found\n"); ++$idx < @list or die("Missing value for -p\n"); my $val = $list[$idx];
Re: find element in array, then advance to next element
by CountZero (Bishop) on Dec 09, 2008 at 17:54 UTC
    Looks more a job for a regular expression than walking an array:
    my $ports = $args =~ m/-p\s+([-\d]+)/;

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      CountZero - tried this and get a return of "1" for my ports. What'd I'd really like is to grab all values (in my example above, 1-1024), then I'll split from there.

        You need list context to assign the capture(s) — note the parentheses around $ports:

        my ($ports) = $args =~ m/-p\s+([-\d]+)/;

        Otherwise (in scalar context), you'd get whether the regex matched (thus the 1).