Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Parsing multiple lines based on a given String

by ArifS (Beadle)
on Jun 17, 2016 at 14:28 UTC ( [id://1165981]=perlquestion: print w/replies, xml ) Need Help??

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

I am trying to parse thru a file and find multiple lines in paragraph based on a given String. For example: I need to search by ip - 10.10.10.1, and find the following lines-
Hereis my HOSTNAME1 hosts IP is 10.10.10.1
-and then assign HOSTNAME1 to a Scalar. Any ideas would be greatly appreciated.

Replies are listed 'Best First'.
Re: Parsing multiple lines based on a given String
by haukex (Archbishop) on Jun 17, 2016 at 16:37 UTC

    Hi ArifS,

    This question seems like a simpler version of your previous question from 1.5 years ago, Print lines based on matching words. In that thread, GrandFather wrote some code for you showing one way to parse a data file where records are split on multiple lines. You could use a similar approach here.

    Hope this helps,
    -- Hauke D

Re: Parsing multiple lines based on a given String
by Marshall (Canon) on Jun 17, 2016 at 15:13 UTC
    Your 2 line example is not quite enough to write some code for this.

    Some general advice: It is almost always easier to write "look ahead" rather than "look behind" code. By that I mean that parsing a file like this, I would find the HOSTNAME first and the IP address second. I associate those 2 things together and then decide to keep it or not. This is easier than finding the IP address and then trying to figure out in the previous lines what HOSTNAME it goes with.

    Are you able to make a stab at some Perl code?
    Just a few more example lines would be helpful.

      I can print the 2 lines that I am looking for....

      Original content restored by GrandFather below

      here is what I tried-
      file.txt -------------- object-group network HOSTNAME_1ST network-object host 10.1.1.1 object-group service WEB_TCP tcp port-object eq 80 --------------
      Trying to get the 1st 2 lines while matching an ip address.
      use strict; use warnings; my $iphostname; my $filename = 'file.txt'; open(my $fh, '<:encoding(UTF-8)', $filename) or die "Could not open file '$filename' $!"; for $iphostname ($fh) { print $iphostname if (/^object-group/ ... /(\d{1,3})\.(\d{1,3})\.(\d +{1,3})\.(\d{1,3})$/); }
      it gives me an error - Use of uninitialized value $_ in pattern match (m//) at .......
        To read from a file handle, use the appropriate operator. To match a variable against a regex, you need to tell Perl what variable to match:
        while (my $iphostname = <$fh>) { print $iphostname if $iphostname =~ /^object-group/ .. $iphostname + =~ /.../;

        ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
        What choroba is showing is called the "flip flop" operator. Have a look at this Flipin good, or a total flop? in the tutorials section.

        Other techniques could possibly be applicable, but I don't know enough about what you are doing to make a suggestion. As always, showing some actual code that you are having trouble with is the best way to get quality advice.

        There are a number of ways to implement this code.
        One is shown below.
        Basically, keep track of the last hostname found. When you find a valid ip, and that ip is the one that you are looking for, then that goes with the most previous hostname.
        #!usr/bin/perl use warnings; use strict; my $file =<<END; object-group network HOSTNAME_1ST network-object host 10.1.1.1 object-group network HOSTNAME_2nd network-object host 10.3.1.1 object-group service WEB_TCP tcp port-object eq 80 END my $hostname; open my $fh, '<', \$file or die "unable to open read file $!"; while (my $line = <$fh>) { if (my ($name) = $line =~ /^object-group network (\w+)/) { $hostname = $name; # "last seen hostname" } my ($ip) = $line =~ /(\d+\.\d+\.\d+\.\d+)/; if (defined ($ip) and $ip eq '10.3.1.1') { print "ip $ip goes with host name $hostname\n"; } } __END__ ip 10.3.1.1 goes with host name HOSTNAME_2nd
Re: Parsing multiple lines based on a given String
by NetWallah (Canon) on Jun 17, 2016 at 16:48 UTC
    If the IP address line always follows the hostname line, it may be easier to write the search logic if you read the file in reverse order, using File::ReadBackwards.

            This is not an optical illusion, it just looks like one.

Re: Parsing multiple lines based on a given String
by GotToBTru (Prior) on Jun 17, 2016 at 14:41 UTC

    Start at the beginning: Tutorials. Especially "Getting started with Perl".

    But God demonstrates His own love toward us, in that while we were yet sinners, Christ died for us. Romans 5:8 (NASB)

Re: Parsing multiple lines based on a given String
by SimpleMonk (Sexton) on Jun 18, 2016 at 03:07 UTC

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1165981]
Approved by GotToBTru
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (6)
As of 2024-04-18 08:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found