in reply to Convert from awk to perl

I second the recommendation: start by trying a2p.

But if that doesn't work, you're in luck - perl and awk are very similar.

First, save a few outputs from sar, so you can test your script. Run those sar outputs thru your awk script (removing >> "sarnetwork" so you get the output on the console) so you know what your perl script should generate.

The next thing you need to do to accent those similarities is use the -a and -ne switches to perl. -a makes perl "autosplit" its input the same way awk does, and -ne makes perl run the command line expression you're about to pass for every line of input, the same way awk does.

The next thing to remember is that while awk splits its input line into $1, $2, $3, thru $NF, perl splits it into $F[0], $F[1], ... $F[$#F] (when using the -a switch). Note that indexes in awk are 1-based, but perls are 0-based, so $1 becomes $F[0].

Once you've replaced all the $[0-9] variables with their $F[] equivalents, you need to add a $ in front of all your variables, since that's how perl refers to scalars. You also need to terminate your statements with semicolons.

So

process=1
becomes
$process=1;

In perl, substr indexes are 0-based, so you'll need to subtract 1 from all the arguments to substr.

Perl makes building up strings simpler via something called interpolation, so

print datehradr":"datemmadjr...
becomes
# perl's print doesn't add in the \n for you print "$datehradr:$datemmadjr...\n"

Finally, it isn't QUITE so easy in perl to append to a file, but you can let the shell do that for you by putting the >> sarnetwork after the whole command.

So here's some COMPLETELY untested code for you to try. You should actually take everything between "perl" and ">>" and move it into a separate script, to simplify testing. But here's the whole command line:

sar -n DEV -f sa17|perl -a -ne' BEGIN { $mydate="2008-02-17"; $lastdate=99; } { $process=0; if ( substr($F[2],0,3) eq "eth" ) { $process=1; } if ( substr($F[2],0,3) eq "bon" ) { $process=1; } if ( $F[2] eq "eth0" ) { $process=1; } if ( ! ( $F[1] eq "AM" || $F[1] eq "PM" ) ) { $process=0; } if ( $F[2] eq "IFACE" ) { $process=0; } if ( $process == 0 ) { next; } $currentdate=$F[0]; if ( $lastdate != $currentdate && $lastdate != 99 ) { print "$datehradj:$datemmadj:$datessadj $myeth0 $myeth1\n" +; $mybond0=0; $myeth0=0; } if ( $F[2] eq "eth0" ) { $myeth0=$F[5]; } if ( $F[2] eq "eth0" ) { $myeth1=$F[6]; } $filetime=$F[0]; $filehour=substr($filetime,0,2); $fileminute=substr($filetime,3,2); $filesecond=substr($filetime,6,2); if ( $F[1] eq "AM" && $filehour == 12 ) { $filehour="00"; } if ( $F[1] eq "PM" && $filehour < 12 ) { $filehour=$filehour+12; } $filedaysecs=(($filehour*60*60)+($fileminute*60)); $dateadj=(int(( $filedaysecs + 300 ) / 600) * 600); $datehradj=int(((int(( $filedaysecs + 300 ) / 600) * 600)) / 3 +600 ); $datemmadj=int((((int(( $filedaysecs + 300 ) / 600) * 600)) % +3600 ) / 60 ); if ( $datehradj == 0 ) { $datehradj="00"; } if ( length($datehradj) == 1 ) { $datehradj="0$datehradj"; } if ( $datemmadj == 0 ) { $datemmadj="00"; } $datessadj="00"; $lastdate=$F[0]; } END { print "$datehradj:$datemmadj:$datessadj $myeth0 $myeth1\n"; }' >> sarnetwork
Edit: Added the eq and if brace fixes from philipbailey and Anonymous Monk below, thanks!

Mike

Replies are listed 'Best First'.
Re^2: Convert from awk to perl
by philipbailey (Curate) on Jul 19, 2008 at 11:50 UTC
    That won't quite work--braces, {}, are always required for blocks in Perl. So, for instance, the first "if" statement would need to be written as:
    if ( substr($F[2],0,3) eq "eth" ) { $process=1; }
    Update: Or to be a bit more "Perlish" you could write:
    $process=1 if (substr($F[2],0,3) eq "eth");
    Update 2: Correction of string comparisons, as per Anonymous Monk.
      strings are compared with eq, numbers with ==