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

for example if I have a file like:
----BOF---- ##head## servername abc xxx xxx serverip: 123 xxx ##head## -------- ##head## servername def xxx xxx serverip: 456 serverip: 445566 xxx ##head## ##head## servername ghi xxx xxx serverip: 789 xxx ##head## ------EOF----
I want to read in where it says head and then store servername and serverip and print them so the desired out put is..
abc,123
def,456,445566
ghi,789

Replies are listed 'Best First'.
Re: perl / grep help
by kyle (Abbot) on Jan 08, 2008 at 17:32 UTC

    This is sort of quick and dirty, but it's a start:

    my %out; while (<DATA>) { if ( /##head##/ ) { if ( %out ) { print join ',', $out{servername}, @{ $out{serverip} }; print "\n"; } %out = (); } $out{servername} = $1 if /^servername\s+(.*)/; push @{$out{serverip}}, $1 if /^serverip:\s+(.*)/; } __DATA__ ##head## servername abc xxx xxx serverip: 123 xxx ##head## -------- ##head## servername def xxx xxx serverip: 456 serverip: 445566 xxx ##head## ##head## servername ghi xxx xxx serverip: 789 xxx ##head##

    Outputs:

    abc,123 def,456,445566 ghi,789
      Rather than a bunch of "if you see this pattern, do this step" kind of things, this would be a good case for dispatch tables.
Re: perl / grep help
by NetWallah (Canon) on Jan 08, 2008 at 17:34 UTC
    "grep" is not the appropriate function here.

    You should consider using regular expressions to capture the parts you want, and assemble them.

    Please post some code, so we know that you have attempted to solve this -- you can then seek assistance with your code, rather than expect the community here to do your work for you.

         "As you get older three things happen. The first is your memory goes, and I can't remember the other two... " - Sir Norman Wisdom

Re: perl / grep help
by spx2 (Deacon) on Jan 08, 2008 at 23:14 UTC
    if your text file was named test.txt then you could have written a "many"-liner to process it
    cat test.txt | perl -ne '($key,$value)=/(servername |serverip: )(.*)/; +if($key eq "servername "){$data->{$value}=[] unless exists $data->{$k +ey};$last_servername=$value;};if($key eq "serverip: "){push @{$data-> +{$last_servername}}, $value};END{printf "%s,%s\n",$_,join ",",@{$data +->{$_}} for keys %$data;}'
    you can use the indent unix utility to sort out the code in a readable manner ,but
    what the code does is really just takes each line ,sees if its a servername or serverip,if its
    a servername that has not been yet encounteret it creates a new arrayref as value of the actual
    servername and if its a serverip it checks the last parsed servername and pushes in the appropriate arrayref
    the server ip.
    at the end, we use the block END to denote the end of the processing of pipe contents
    so we now can print out the results,the code for printing can be seen in the END block.
    def,456,445566 abc,123 ghi,789