I am currently available as a freelance Senior Perl Programmer. Download my up-to-date resume (PDF)
John Bokma MexIT
freelance Perl programmer

Using Perl to process fields II

Thursday, February 24, 2005 | 0 comments

Yesterday I posted a short Perl solution to a problem given by Kees de Koster in the Dutch newsgroup nl.comp.os.linux.programmeren. My solution was met by Koos with:

AAAAARRRRGHHHH!!!!
'dorie John, hou daar nu eens me op!

(Damn John, stop doing that). So when Kees posted more information on his problem and his own solution written in Perl, I couldn't resist to call the Perl solution in my reply the "Koos special of the day".

An example of new input data, as given by Kees:

ChartPath=/home/sircrow/Qtstalker/data/Stocks/AAB
0=Plugin=HorizontalLine|Name=0|Value=19.9431|Plot=Main Plot|Color=#0055ff
19940103000000=8.15,8.36,8.13,8.33,2893070
19940104000000=8.35,8.35,8.26,8.26,4084400
19940105000000=8.33,8.33,8.28,8.3,5622470
20050218000000=21.16,21.28,21.08,21.16,6017510
20050221000000=21.17,21.19,20.82,20.88,6842220
BarType=0
CHARTOBJECTS=0
Plugin=Stocks
Symbol=AAB
Title=AAB
Type=Stock

Which, according to the same posting, when a factor of 4 is used for multiplication, should result in the following output:

ChartPath=/home/sircrow/Qtstalker/data/Stocks/AAB
0=Plugin=HorizontalLine|Name=0|Value=19.9431|Plot=Main Plot|Color=#0055ff
19940103000000=32.6,33.44,32.52,33.32,723267
19940104000000=33.4,33.4,33.04,33.04,1021100
19940105000000=33.32,33.32,33.12,33.2,1405617
20050218000000=84.64,85.12,84.32,84.64,1504377
20050221000000=84.68,84.76,83.28,83.52,1710555
BarType=0
CHARTOBJECTS=0
Plugin=Stocks
Symbol=AAB
Title=AAB
Type=Stock

Moreover, from the solution Kees had made I understood that only if the value in front of the = character was greater than 19000000000000 action should be taken. Besides, the number in the last column should divided by the given factor and turned into an int. So my Perl solution became:

#!perl -spaF[=,]

next unless $F[0] > 19000000000000;
$_ = "$F[ 0 ]=" . join ',', (

    map { $_ * $factor } @F[ 1..4 ]

), int( $F[ 5 ] / $factor ) . "\n"

How the Perl program works

Again, the first line of the Perl program does most of the work. The -s switch enables rudimentary switch parsing on the command line after the script name but before any filename arguments. I used it to pass the value of the factor, for example -factor=4 sets the value of $factor to the number 4.

The -p switch works similar to the -n switch (see: Using Perl to process fields) put it does an additional print;, ie it prints the value contained in the $_ variable. And like with the previous Perl solution the -a switch is used in combination with -F to split each line on either the , or the = character.

In the actual code I first test if the value of the first column is greater than 19000000000000. If not, then move on (and the -p switch makes sure that the input is copied 1:1 to the output). The next line multiplies the values in the 2nd up to and including the 5th column, and does the integer division on the 6th. A join is used to glue the values together, separated by commas.

The Perl program should be called as follows:

program -factor=n file > out

In order to make sure my Perl program gave the desired output, I piped the output to md5sum and compared it with the md5sum I calculated from the result given by Kees.

kees-sol2.pl -factor=4 kees-in-2.txt | md5sum
e800ee35c08e70b4ceae4e4096e77013 *-

md5sum kees-out-2.txt
e800ee35c08e70b4ceae4e4096e77013 *kees-out-2.txt

Since the MD5 digest of the program is identical to the output given by Kees it's safe to assume that the Perl program I wrote works correctly.

Processing fields related

Also today

Please post a comment | read 0 comments | RSS feed