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

Monks, I have a system utility (sysutil) on a Solaris 9 box that produces output similar to the following:
HOST ID APP CONN SESS JOB server 0 applic 14:40:28 0 0 0 server 1 applic 14:40:28 0 0 0 server 2 applic 14:40:28 0 0 0 server 3 applic 14:40:28 0 0 0 server 4 applic 14:40:28 0 0 0 server 5 applic 14:40:28 0 0 0 server 6 applic 14:40:28 0 0 0 server 7 applic 14:40:28 0 0 0 Total 0 0 0
In my perl script, I want to extract just the Total line (which can be in various places depending on the number of servers in the list). I am using the following, which I would expect to work, but it returns null. Any ideas on what I'm doing wrong?
$part = `sysutil | awk '{print \$2,\$3,\$4,\$5}'| grep Total`;

Replies are listed 'Best First'.
Re: extract problem
by ikegami (Patriarch) on Sep 22, 2005 at 19:57 UTC

    For the total line, isn't $1="Total", $2="0", $3="0", $4="0", $5="", $6=""? Try:

    my $part = `sysutil | grep Total`;

    or just

    my ($part) = grep { /^\s*Total/ } `sysutil`;

    Of course, you probably want to extract the three numbers:

    my ($conn, $sess, $job) = (split(/\s+/, (grep { /^\s*Total/ } `sysutil +`)[0]))[2..4];

    Update: Ug, that was ugly, let's try:

    my ($part) = grep { /^\s*Total/ } `sysutil`; my ($conn, $sess, $job) = (split(/\s+/, $part))[2..4];

    or

    my ($conn, $sess, $job) = `sysutil` =~ /^ \s+ Total \s+ (\S+) \s+ (\S+) \s+ (\S+) /xm;

    or functional style

    sub select_fields { @_[@{shift(@_)}] } sub head { $_[0] } # Shortcut for "select_fields [0]," my ($conn, $sess, $job) = select_fields [2..4], # Extract totals. split /\s+/, # Split into fields. head # List to scalar. grep { /^\s*Total/ } # Extract total line. `sysutil`; # Get data.

    Update: Forgot that `` in list context splits on $/. Simplified the above. jpeg++.

Re: extract problem
by jpeg (Chaplain) on Sep 22, 2005 at 20:12 UTC
    awk would think "Total" is field $1, no?

    I reckon I'd avoid the pipe to awk and grep; perl can do it instead:

    my @sysutiloutput = `sysutil`; my @total = grep (/Total/, @sysutiloutput); print ("@total\n");
    --
    jpg
Re: extract problem
by NetWallah (Canon) on Sep 22, 2005 at 20:39 UTC
    You should be able to simplify the code down to:
    my ($tot)= grep /Total/, qx[sysutil]; print $tot; # Should already include "\n"
    Note the use of the list context in declaring $tot - this finds you the FIRST instance of "Total".

    Efficiency experts (Nit pickers) may want an early exit out of the "grep", but I think , in this, presumably reletively infrequent usage, simplicity overrides.

    You can parse $tot for the numeric values with a regex or split, if necessary.

    Update:I just noticed that ikegami(++) beat me to it in his second, third and fourth examples. His code is tighter, ensuring that "Total" is the first word on the line.

         "Man cannot live by bread alone...
             He'd better have some goat cheese and wine to go with it!"

Re: extract problem
by ambrus (Abbot) on Sep 23, 2005 at 16:12 UTC

    Why don't you grep first and awk the grepped output?