http://qs321.pair.com?node_id=634372

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

This node falls below the community's threshold of quality. You may see it by logging in.
• Comment on RE: performing calculation in cells in a file

Replies are listed 'Best First'.
Re^2: performing calculation in cells in a file
by marto (Cardinal) on Aug 22, 2007 at 15:06 UTC
Re^2: performing calculation in cells in a file
by FunkyMonk (Chancellor) on Aug 22, 2007 at 15:18 UTC
This does most of the work for you, but I've left some things for you to do:

```<DATA>;

my @prev_line;
while ( <DATA> ) {
my @this_line = split /[,\s]+/;
shift @this_line;
print join( ", ", map { "\$this_line[\$_]-\$prev_line[\$_]" } 0 .. \$#t
+his_line ), "\n"
if @prev_line;
@prev_line = @this_line;
}
__DATA__
date, val1, val2, val3, val4
1/2/2007, 1, 4, 5, 6
1/3/2007, 2, 5, 7, 10
1/5/2007, 5, 6, 8, 11

Output:

```2-1, 5-4, 7-5, 10-6
5-2, 6-5, 8-7, 11-10

You may find this version easier to follow (using the same __DATA__ as earlier):

```<DATA>;

my @prev_line;
while ( <DATA> ) {
my @this_line = split /[,\s]+/;
shift @this_line;

if ( @prev_line ) {
my @output;
for ( 0 .. \$#this_line ) {
push @output, "\$this_line[\$_]-\$prev_line[\$_]";
}
print join( ", ", @output ), "\n";
}
@prev_line = @this_line;
}

That leaves you with the job and handling the files.

I'm sure google will help, and there's always the Perl documentation.

update: omitted __DATA__ first time round

Re^2: performing calculation in cells in a file
by rvosa (Curate) on Aug 22, 2007 at 15:30 UTC
Can you give some example of the actual file, e.g. copy a few lines and paste it here in a reply, enclosed in <code></code> tags. Is it a comma-separated file? A spreadsheet of some kind (as the earlier replier inferred)?

I think it's like this:
```1/2/2007, 1, 4, 5, 6
1/3/2007, 2, 5, 7, 10
1/5/2007, 5, 6, 8, 11
And I think the logic is that the date of each line needs to be stripped, and the subsequent entries need to be "subtracted" or hyphen-separated from those in the same column of the previous line. Maybe something like this works:
```my @previous;
while(<>){
chomp;
my @current = split /,/, \$_;
if ( not @previous ) {
print join ',', @current[ 1 .. \$#current ];
print "\n";
}
else {
for my \$i ( 1 .. ( \$#current - 1 ) ) {
print \$current[\$i], '-', \$previous[\$i], ',';
}
print \$current[-1], '-', \$previous[-1], "\n";
@previous = @current;
}
}