in reply to Re: Slurping file using regular expressions for array or variables
in thread Slurping file using regular expressions for array or variables

Thank you for your replies. Sorry about the munging of the previous post. I'm trying to populate the two arrays @IPADR and @MACADR using a binding to a slurped file using captures from regular expressions shown below. In between the two captures I put "..." since I wasn't sure what to put there. I had "*." on the assumption that the second capture would limit the dot's greediness. If I remove one of the captures and just use a single related array, I can print the values. As soon as I try to put the second capture into the regular expression, I get no output and no error message (running perl -w script.pl). I thought two captures could be used to populate separate arrays but there is something I am unaware of. I'm hoping it's not something you told me previously. the eginv.txt file that the regular expression is bound to has around 100 nodes in it, each with their own rows for mac addresses and ip addresses etc. I'd like to get the values into their respective arrays so I could print them so that each node is described on one line like this "NODENAME, IPADDRESS, MACADDRESS, SOMETHINGELSE...." Can I get that with some modifcations to what I have so far? Thanks

This is the source of the information the script is running against sh +owing one node of about 100. Nmap scan report for somenode.somedomain.com (192.x.x.x) Host is up (0.032s latency). Not shown: 974 closed ports PORT STATE SERVICE 53/tcp open domain ... 49160/tcp open unknown MAC Address: 24:34:E4:57:aB:BC (some company) Device type: general purpose Running: Microsoft Windows 7|2008 OS CPE: cpe:/o:microsoft:windows_7::- cpe:/o:microsoft:windows_7::sp1 cpe:/o:microsoft:windows_server_2008::sp1 cpe:/o:microsoft:windows_8 OS details: Microsoft Windows 7 SP0 - SP1, Windows Server 2008 SP1, or + Windows 8 Network Distance: 1 hop
my $file = 'eginv.txt'; { local( $/ ) ; open( my $fh, $file ) or die "Oops file dead\n"; my $TEXT = <$fh>; my $IPADDR=(); my $MACADDR=(); my $RUN=(); my $OSDETL=(); my $HOP=(); my @MACADR=(); my @IPADR=(); (@IPADR,@MACADR) = $TEXT =~ /(192\.168\.1\.[\d]+)...([A-Fa-f0-9]{2}:[A +-Fa-f0-9]{2}:[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}:[A-Fa-f0-9] +{2})/gs; foreach my $ial (@IPADR) { print "$ial\n"; } # foreach my $mal (@MACADR) { # print "$mal\n"; # } }

Replies are listed 'Best First'.
Re^3: Slurping file using regular expressions for array or variables
by ww (Archbishop) on Apr 04, 2014 at 19:20 UTC
    As a wise man once said, 'you can't just make s**t up, and expect the computer to understand.'

    Your three dots between the captures means the second capture will fail unless there are exactly 3 anythings (characters between the first and the second item you're trying to capture.

    Please, do as others have suggested: use perldoc to read the basic regex docs ( perlrequick, perlretut and perlredoc ) until you truly understand at least those elements you're trying to use.


    Questions containing the words "doesn't work" (or their moral equivalent) will usually get a downvote from me unless accompanied by:
    1. code
    2. verbatim error and/or warning messages
    3. a coherent explanation of what "doesn't work actually means.

      Ok, I shouldn't have put dots there - I wasn't trying to use it as a perl wildcard, more like a "etc" which I did not make clear. I had used .* but only got one mac address and one ipaddress. The question isn't related to what goes between the captures but more about whether the two captures can be sent to the arrays. If you have a link for me to read about that, I would be grateful. I don't think writing about making stuff up is useful for feedback although I understand that I should have not use the three dots and used something else to indicate that that wasn't what I was concerned about in that particular post.

        The code below addreses itself solely to your question about how " the two captures can be sent to the arrays.." It is inappropriate and inadqequate for production use in a variety of ways:
        1. It offers no illustration of how to process multiple lines of your source data
        2. it makes no attempt to ensure that your customer can identify a particular IP with its associated MAC address (particularly when the source data is borked)
                  and, very important,
        3. its design is (intentionally) flawed, in that it has no plan to deal with incomplete data, failed matches, and the like, or numerous other problems which may challenge you
        my $text='abc-123'; if ( $text =~ /(abc)-(\d{3})/) { say "\$1 is $1"; # rather than printing the matches, as this doe +s, say "\$2 is $2"; # you could push the matches from each iteratio +n # over the full text to two arrays } # i.e., something like... push @IPs, $1; push @MACs, $2; }

        Almost all (good) introductions to Perl will teach you how to use push very early in the game (again, read the docs!). And had you taken the advice to read the docs on regexen, the code below should have been on the tip of your tongue (or fingertips).

        I may be wrong, of course, but you seem to me to be trying to skip over the sometimes difficult but essential task of getting the basics down pat... so I say again, read the documents. This site has many very fine tutorials; so too, do may colleges and universities (and often those are accessible online at no charge). And if investing in a book is within your means, run -- don't walk -- to your nearest good bookstore and buy a copy of learning Perl.


        Questions containing the words "doesn't work" (or their moral equivalent) will usually get a downvote from me unless accompanied by:
        1. code
        2. verbatim error and/or warning messages
        3. a coherent explanation of what "doesn't work actually means.