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

Hello Guys, I need little bit help. I have file and one part of this file is as follow
New Elements ------------ cgw01.dub01.nsw.sptel.net.au-POS1/0-Path (171) Action: Resolved New (not saved) sysName: cgw01.dub01.nsw.sptel.net.au IP Address: 202.168.55.185 Index1: 9 ifDescr: POS1/0 cgw01.dub01.nsw.sptel.net.au-RH-power-AstecDCPowerSupply-1 (EnvCPU- +power) Action: Resolved New (not saved) sysName: cgw01.dub01.nsw.sptel.net.au IP Address: 202.168.55.185 Index1: 1 ifDescr: EnvCPU-Astec DC Power Supply cgw01.dub01.nsw.sptel.net.au-RH-power-AstecDCPowerSupply-2 (EnvCPU +-power) Action: Resolved New (not saved) sysName: cgw01.dub01.nsw.sptel.net.au IP Address: 202.168.55.185 Index1: 2 ifDescr: EnvCPU-Astec DC Power Supply GROUP ASSIGNMENT DETAILS ========================
I want to grab all devices name like cgw01.dub01.nsw.sptel.net.au-POS1/0-Path ,before the "Action:" option But be rememebr these devices name change frquently. So i need perl pattern matching that can grab all the devices name. Thanks for your time

Edited by planetscape - added code tags

Replies are listed 'Best First'.
Re: Pattern Matching
by McDarren (Abbot) on Apr 14, 2006 at 02:10 UTC
    This smells like homework to me. Especially the bit that goes:
    GROUP ASSIGNMENT DETAILS
    I've never seen anything in an snmp return string that looks like that.

    Anyway, regardless of whether it's homework or not, you're not going to learn much (anything) simply by asking someone else to write some code for you.

    Have a got at it yourself. Have a read through perlre and perlretut. Show that you've made at least some effort to solve this problem for yourself, and you're more likely to get some help here.

    Cheers,
    Darren :)

      hmm. I think you took it wrong. It is not an assignment. It is output of Ehealth discovery. Might be you are unaware of ehealth. I am not perl gurur so thats why i need help if you can not help just done make fun of others the GROUP ASSIGNMENT DETAILS part is as follow GROUP ASSIGNMENT DETAILS ======================== Group names were specified in the Element Filter or the Save
      To Groups options. The Report Only option was specified so group assignments were not performed.
      TIPS
      ==== Discover Key (nms Id):
      This is created by discover to uniquely identify an element.
      eHealth uses the discover key to help resolve changes in your network with your poller configuration.
      Duplicate Element Names:
      These elements are newly discovered and have the same names as existing elements. Discover did not update the existing elements because their attributes did not match. Instead, eHealth made these element names unique.
        I think you took it wrong. It is not an assignment.
        Well, perhaps I did. But that doesn't alter the fact that you haven't demonstrated that you've made any effort to solve this particular problem for yourself. Perlmonks is not a free code writing service.

        Anyway, here are a few pointers to get you started.

        You say that the data is in a file, so the first thing you need to do is open the file for reading. This is generally done like so:

        open DATA, "<", $myfile or die "Could not open $myfile:$!\n";
        Next you want to decide what sort of data structure you're going to use. Let's say you just want to gather the device names into a list. Therefore, you declare your list variable:
        my @devices;
        Now you'll need to iterate through the file, line by line, extracting the data you want and adding it to the list. You'll need three things:
        • a loop.
        • a pattern match, and
        • a push statement.
        You might write something like this:
        while (<DATA>) { chomp; next if !/^cgw01/; push @devices, $_; }
        You may need to refine the pattern match, depending on how variable your data is. The above assumes that all the device names begin with the string "cgw01".

        Make sure you use strict and use warnings, and make use of print statements and Data::Dumper::Simple for debugging.

        Cheers,
        Darren :)

        A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Pattern Matching
by strat (Canon) on Apr 14, 2006 at 09:22 UTC

    Well, if you just need the line before \nAction, you could try something like:

    my @deviceNames = do { open (my $FH, "<", $file) or die "Error: couldn't read '$file': $!\n"; # split up lines by \nAction: within the do-block local $/ = "\nAction:"; my @deviceNames = (); while (my $block = <$FH>) { # extract the last line my $deviceName = ( split(/\n/, $block) )[-1]; push (@deviceNames, $deviceName) if $deviceName; } # while # well, the following line is not really needed, because # $FH is automatically closed at the end of the do-block close ($FH); @deviceNames; } ; # do

    or the like (not tested)

    Best regards,
    perl -e "s>>*F>e=>y)\*martinF)stronat)=>print,print v8.8.8.32.11.32"

Re: Pattern Matching
by QM (Parson) on Apr 14, 2006 at 16:29 UTC
    This might DWIM:
    #!/your/perl/here use strict; use warnings; my $last_line; while (<>) { if ( m/^Action:/ ) { print $last_line; } $last_line = $_; }
    Assuming you put this in file find_devices, and your input file is called new_elements, you would run it like this:
    perl find_devices new_elements
    Please let us know if this works for you, or if it doesn't, why not.

    Update:

    For the rest of us, I've prefer this solution for newbies (having had a lot of interaction with some of them lately). There's no explicit open or close, there are only 2 variables mentioned (and only 1 needs to be declared), there's 1 while, 1 if, and 1 print. This could easily be a 1 liner:

    perl -ne 'print $x if /^Action:/; $x=$_;' new_elements

    -QM
    --
    Quantum Mechanics: The dreams stuff is made of