Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Its a pretty simple question.. though embarassed to ask but i am totally new in perl

by gb92 (Initiate)
on Aug 13, 2013 at 10:58 UTC ( [id://1049248]=perlquestion: print w/replies, xml ) Need Help??

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

its a simple 2 arrays and i want to subtract them with different rows name .. for example

file1

acv sad das

21 43 33

23 33 21

file2

cvc bgb cdc

12 32 32

32 32 32

and subtract them and create a new file with different header names of rows and columns such as file 3

qwqe wqwe ewq

- - -

- - -

and file 3 shuld have a threshold defined in argument dat if after subtraction it z more than 5 or 10 (as defined in argument) it shuld only print those values ! till now code done as follows:

use autodie; use List::Util qw(max); use strict; use warnings; my $file1=$ARGV[0]; my $file2=$ARGV[1]; my $file3=$ARGV[2]; open( my $in1, "<", $file1); open( my $in2, "<", $file2); open( my $out, '>', $file3); while (! eof($in1) && ! eof($in2)) { chomp(my $line1 = <$in1>); chomp(my $line2 = <$in2>); my @line1 = split ' ', $line1; my @line2 = split ' ', $line2; my @out = map {$line1[$_] - $line2[$_]} (0..max($#line1,$#line2)); print $out join(' ', @out), "\n"; } warn "Premature end of file: $file1" if ! eof($in2); warn "Premature end of file: $file2" if ! eof($in1);

now i am stuck .. dont know how to go next.. () and 1 more problem how to ignore the 1st row because while subtracting d names of rows and columns are troubling me..

  • Comment on Its a pretty simple question.. though embarassed to ask but i am totally new in perl
  • Download Code

Replies are listed 'Best First'.
Re: Its a pretty simple question.. though embarassed to ask but i am totally new in perl
by Laurent_R (Canon) on Aug 13, 2013 at 21:42 UTC

    OK, following your messages on the chatterbox (I was not really on-line, I just had my browser still open on Perlmonks, but was not in front of my computer), I've just prepared a new version of the code that I supplied earlier.

    I can't say if it does what you want, because I am still not even sure that I understood what you really want and because I don't have actual sample files on which to run tests, but at least, I tested that it should compile cleanly without any error or warning:

    use strict; use warnings; my $file1=$ARGV[0]; my $file2=$ARGV[1]; my $file3=$ARGV[2]; open my $in1, "<", $file1 or die "unable to open $file1 $!"; open my $in2, "<", $file2 or die "unable to open $file2 $!"; open my $out, '>', $file3 or die "unable to open $file3 $!"; my $header1 = <$in1>; my $header2 = <$in2>; print $out "some header for output file \n"; # now you are all set with headers, you can focus on the data while (my $line1 = <$in1>) { my $line2 = <$in2>; last unless defined $line2; chomp ($line1, $line2); my @values1 = split $line1; my @values2 = split $line2; my @values3 = map {$values1[$_] - $values2[$_]} 0..$#values1; print $out "@values3 \n"; }

    This what it should do:

    • read the first line of file1 and file 2 (the headers) and discard them;
    • write a silly header in file3 (you can just change it in accordance with your needs);
    • read into $line1 and $line2 the next line from file1 and file2 respectively;
    • split $line1 and $line2 into the @values1 and @values2 arrays;
    • substract respective values of @values2 from @values1;
    • output the restults of these substractions to the output file;
    • repeat the last four steps for the next line, until the files are exhausted.

    So, if file1 has:

    foo bar baz 43 41 67

    And file2 has:

    foo bar baz 41 2 60

    The output would be:

    Some new header to be determined 2 39 7

    That is at least what I understood from your initial description of your requirement.

    As I already said, this program would need additional error-handling code (if the files don't match), but I am not going to go into that so long as I don't even know if this is what you need.

      thank you so much laurent sir ! understood it quite well really thanks a lot sir :) and yes this was what i needed

Re: Its a pretty simple question.. though embarassed to ask but i am totally new in perl
by Anonymous Monk on Aug 13, 2013 at 11:07 UTC

    now i am stuck .. dont know how to go next.. ()

    Explain what you want to do next, what output you want to accomplish

    and 1 more problem how to ignore the 1st row because while subtracting d names of rows and columns are troubling me..

    Its simple, next, $.

    You can also readline before you enter loop to burn the first line

      Basically i am working on dz: TWO files with some format will be arguments to script Threshold value option such as “-th 5k/M”. This option would mean that 5kb or 5mb of the memory is allowed to be used as threshold. Output from perl script: Diff the files, save it to 3rd file and just print PASS/FAIL depending on the threshold specified. Table used in this format:

      MemU MemA MemF StreamName

      489 489 0 -

      11 11 0 -

      5 5 0 -

      505 505 0 Totals

      where to use next; because its going in infinite loop .. how should i use next statement fr bth d files !

        The suggestion was to use next to skip the header line if either you recognize it as a header (for example with a regex), or you know that it is the first line of the file because the $. special variable (line number in the last read file) is equal to 1, something like this:

        next if $. == 1;

        In my example program, I used a third solution: to read (and discard) one line of input of each file before entering into the while loop. This is slightly faster when reading huge files, since it removes a test from the inner loop, but the difference is probably pretty small.

Re: Its a pretty simple question.. though embarassed to ask but i am totally new in perl
by Laurent_R (Canon) on Aug 13, 2013 at 14:16 UTC

    The easiest to handle the headers is to read from the file once before going into the while loop. Also, check the return status of your open statements. You might try something like this (untested, and not sure this is really what you want):

    # ... open my $in1, "<", $file1 or die "unable to open $file1 $!"; open my $in2, "<", $file2 or die "unable to open $file2 $!"; open my $out, '>', $file3 or die "unable to open $file3 $!"; my $header1 = <$in1>; my $header2 = <$in2>; print $out "some header for output file \n"; # now you are all set with headers, you can focus on the data while (my $line1 = <in1>) { my $line2 = <in2>; last unless defined $line2; chomp $line1, $line2; my @values1 = split $line1; my @values2 = split $line2; my @values3 = map {$values1[$_] - $values2[$_]} 0..$#values1; print $out "@values3 \n"; }

    More code is needed for error handling (what is one line has more items than the other? etc.), but I guess you get the basic idea.

    Update: removed sentence about return status of return statement, I had not paid attention to the use autodie statement. Also corrected a couple of typos in the code.

      Also, check the return status of your open statements

      That is what autodie does for the OP

        Right, I did not notice the use autodie statement.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1049248]
Approved by vinoth.ree
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (4)
As of 2024-04-20 03:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found