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

Hello Monks! I again have gotten in over my head and need guidence. Here is my delema. I have a command that produces output like this:

ACTIVE FULL SUSPENDED FROZEN IMPORTED ST0315 (FROZEN) ST0306 (FROZEN) ST0304 (FROZEN) ST0314 (FROZEN) ST0308 (FROZEN) ST0309 (FROZEN) ST0312 (FROZEN) ST4910 (FROZEN) ST4782 expires 06/19/2004 22:00 (FROZEN) ST2838 expires 07/09/2004 20:46 (FROZEN) ST4173 expires 07/10/2004 20:30 (FROZEN) ST1606 expires 07/14/2004 22:43 (FROZEN) ST4717 expires 05/14/2004 00:55 ST6481 expires 05/16/2004 05:22 ST2058 expires 05/16/2004 03:55 ST6540 expires 05/16/2004 01:36 ST6476 expires 05/16/2004 01:18 ST6486 expires 05/16/2004 01:35 ST1467 expires 05/16/2004 03:55 ST4730 expires 05/16/2004 01:48 ST5353 expires 05/16/2004 01:35 ST5833 expires 05/16/2004 01:36 ST3325 expires 05/16/2004 01:25 ST5413 expires 05/16/2004 01:18 ST5676 expires 05/16/2004 01:49 ST2044 expires 05/16/2004 01:46 ST3276 expires 05/16/2004 01:04
here is my script:
#!/usr/local/bin/perl open (IMAGES, "/usr/openv/netbackup/bin/admincmd/bpmedialist -summary +|"); open (HTML, ">/usr/openv/netbackup/stats/frozen.html") || die "Can't o +pen output!"; select(HTML); set_date(); match(); sort_tapes(); write_html(); close IMAGES; close HTML; ## ## Subroutines... ## ## sub set_date { my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time); ($mday < 10) ? ($mday = 0 . $mday) : ($mday =+ $mday); (($mon + 1) < 10) ? ($mon = 0 . ($mon + 1)) : $mon++; my $stamp; $hour = 0 . $hour if ($hour < 10); if ($hour > 12) { $hour = $hour - 12; $stamp = 'PM'; } elsif ($hour eq '12') { $stamp = 'PM'; } else { $stamp = 'AM'; } $min = 0 . $min if ($min < 10); $sec = 0 . $sec if ($sec < 10); my ($date_today) = $mon . '/' . $mday . '/' . $year; my ($time) = $hour . ':' . $min . ':' . $sec . " $stamp"; $rdate_today = \$date_today; $rtime = \$time; } sub match { while (<IMAGES>) { if ($_ =~ /^(\s+)MVA/o) { $_ =~ s/(\s+)//o; chop; my ($tape_id, $expiration, $date, $time, $stat +us) = split (/ /) create_entry($tape_id, $expiration, $date, $ti +me, $status) if ($status eq "(FROZEN)"); } } } sub create_entry { my ($tape_id, $index, $date, $time, $status) = @_; my ($rlEntry) = [$tape_id, $index, $date, $time, $status]; push (@{$tape_index{$tape_id}}, $rlEntry); } sub sort_tapes { my %hold_sort; foreach $tape (sort keys %tape_index) { my ($rlEntry) = @{$tape_index{$tape}}; push (@{$hold_sort{$rlEntry->[1]}}, $rlEntry); } %tape_index = %hold_sort; } sub write_html { print "<HTML><HEAD><TITLE>Netbackup Frozen Tape Report</TITLE> +<H1><CENTER>HEVA-ATL Frozen Tape Report</H1></CENTER></HEAD><B R><CENTER><FONT SIZE=5>Last updated: $$rdate_today <BR>at $$rtime </FO +NT></CENTER><BODY BGCOLOR=white><BR><BR><CENTER><TABLE BORDER= 4 WIDTH=60%><TR ALIGN=CENTER><TD>Media ID</TD><TD>Expiration Date</TD> +<TD>Expiration Time</TD></TR>\n";<br> if (@{$tape_index{expired}}) { print "<TR ALIGN=CENTER><TD COLSPAN=3>Currently Frozen + Tapes (remove)</TD></TR>\n"; foreach $tape (@{$tape_index{expired}}) { print "<TR ALIGN=CENTER><TD>$tape->[0]</TD><TD +>$tape->[2]</TD><TD>$tape->[3]</TD></TR>\n";<br> } } else { print "<TR ALIGN=CENTER><TD COLSPAN=3>No currently exp +ired FROZEN tapes</TD></TR>\n"; } if (@{$tape_index{expires}}) { print "<TR ALIGN=CENTER><TD COLSPAN=3>The following ar +e FROZEN but NOT yet expired</TD></TR>\n"; foreach $tape (@{$tape_index{expires}}) { print "<TR ALIGN=CENTER><TD>$tape->[0]</TD><TD +>$tape->[2]</TD><TD>$tape->[3]\n</TD></TR>";<br> } } else { print "<TR ALIGN=CENTER><TD>No other frozen tapes.</TD +></TR>"; } print "</TABLE></CENTER></BODY></HTML>\n"; }
even though FROZEN appears in the output of the first command I am not getting any matches? Can anyone give me some insight on this? It always tells me It cant find anything that matches frozen. Thanks!

Edited by theorbtwo: Add code tags, remove br tags.

janitored by ybiC: Retitle from antithetical "Clueeless and need help". But I *do* mean that in the kindest possible way, mrbbq. 8^)

Replies are listed 'Best First'.
Re: Parse backup log
by matija (Priest) on Apr 20, 2004 at 19:25 UTC
    You're doing a split(/  /), not a split(/\s+/).

    By default, split preserves the empty leading fields. That means that you're probably getting empty values in your ($tape_id, $expiration, $date, $time, $status) list.

    If you had printed the values out right after split, you'd have seen it.

    I suggest you use ($blank,$tape_id, $expiration, $date, $time, $status)=split(/\s+/) and see it that brings you closer to the solution. ($blank will be empty, of course).

Re: Parse backup log
by Belgarion (Chaplain) on Apr 20, 2004 at 19:37 UTC

    In addition to matija's suggestion, you appear to need to also take into account lines which do not contain the expires, date, and time fields. In those cases, even with matija's example, your status variable would be undefined (or blank.)

      even after the changes I am still not getting any matches on frozen? My code as it stands now is like this:
      sub match { while (<IMAGES>) { if ($_ =~ /^(\s+)MVA/o) { $_ =~ s/(\s+)//o; chop; #my ($tape_id, $expiration, $date, $time, $sta +tus) = split (/ /); my ($blank, $tape_id, $expiration, $date, $tim +e, $status)=split(/\s+/); #create_entry($tape_id, $expiration, $date, $t +ime, $status) create_entry($blank, $tape_id, $expiration, $d +ate, $time, $status) if ($status eq "(FROZEN)"); #if ($status eq /FROZEN/); } } }
      and i still get no matches in the html form?

      Edited by theorbtwo to add code tags, and remove br tags.

        Wait a second. Where did the

        if ($_ =~ /^(\s+)MVA/o) {
        come from? None of your IMAGE lines begin with MVA (with or without spaces.) Your match routine looks for lines beginning with MVA before trying to do the create_entry() function. Given the input you've supplied, it will never match any lines.

        I'm pretty confused at this point.

Re: Parse backup log
by Belgarion (Chaplain) on Apr 20, 2004 at 19:16 UTC

    Wow. You might want to reformat your question using the CODE tags to keep your example from messing up the display.

    Update I should not try answering questions without drinking my coffee first. My first answer was completely wrong.

    Update II Okay, let's try this again. Are you getting any frozen type rows correctly? I would imagine the rows that just have tape_id and status are not being displayed at all. What about the other rows that have tape_id, expiration, date, time, and status? Are they displaying?

      I am not getting anything and when it generates the html file it simply appears blank. Below is the output after the script runs and frozen tapes are present.
      <HTML><HEAD><TITLE>Netbackup Frozen Tape Report</TITLE><H1><CENTER>HEV +A-ATL Frozen Tape Report</H1></CENTER></HEAD><BR><CENTER><FONT SIZE=5>Last updated: 04/20/104 <BR>at 12:29:42 PM </FONT></CENTER><BO +DY BGCOLOR=white><BR><BR><CENTER><TABLE BORDER=4 WIDTH=60%><TR ALIGN=CENTER><TD>Media ID</TD><TD>Expiration Date</TD><TD>Expiration +Time</TD></TR> <TR ALIGN=CENTER><TD COLSPAN=3>No currently expired FROZEN tapes</TD>< +/TR> <TR ALIGN=CENTER><TD>No other frozen tapes.</TD></TR></TABLE></CENTER> +</BODY></HTML>

      Edited by theorbtwo: Added code tags.

Re: Parse backup log
by blue_cowdawg (Monsignor) on Apr 20, 2004 at 22:05 UTC

    Here's a framework you can work with:

    <DATA>; #Get rid of the header. while(my $item=<DATA>){ chomp $item; next if not $item =~ /FROZEN/; $item =~ s/^\s+//; # Get rid of leading spaces my @f=split(/\s/,$item); my $state=pop @f; if ( $#f == 0 ) { push @f," "," "," "; } push @f,$state; printf "%s\n",join(",",@f); printf "<tr>%s</tr>\n",join " ",map { "<td>" . $_ . "</td>" } @f; } __END__ ACTIVE FULL SUSPENDED FROZEN IMPORTED ST0315 (FROZEN) ST0306 (FROZEN) ST0304 (FROZEN) ST0314 (FROZEN) ST0308 (FROZEN) ST0309 (FROZEN) ST0312 (FROZEN) ST4910 (FROZEN) ST4782 expires 06/19/2004 22:00 (FROZEN) ST2838 expires 07/09/2004 20:46 (FROZEN) ST4173 expires 07/10/2004 20:30 (FROZEN) ST1606 expires 07/14/2004 22:43 (FROZEN) ST4717 expires 05/14/2004 00:55 ST6481 expires 05/16/2004 05:22 ST2058 expires 05/16/2004 03:55 ST6540 expires 05/16/2004 01:36 ST6476 expires 05/16/2004 01:18 ST6486 expires 05/16/2004 01:35 ST1467 expires 05/16/2004 03:55 ST4730 expires 05/16/2004 01:48 ST5353 expires 05/16/2004 01:35 ST5833 expires 05/16/2004 01:36 ST3325 expires 05/16/2004 01:25 ST5413 expires 05/16/2004 01:18 ST5676 expires 05/16/2004 01:49 ST2044 expires 05/16/2004 01:46 ST3276 expires 05/16/2004 01:04