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

hi
open FILE1,"1.txt" or die "can't open file 1"; open FILE2,"2.txt" or die "can't open file 2"; open(w1,">3.txt"); open(w2,">4.txt"); while (my $line1 = <FILE1>) { chomp $line1; my @cond1 = split("\t" , $line1); print "$cond1[2]\n"; while (my $line2 = <FILE2>) { chomp $line2; my @cond2 = split("\t" , $line2); print "$cond2[2]\n"; if(abs($cond1[2]-$cond2[2])>=2) { print w1 "$line1\n"; print w2 "$line2\n"; } } } close FILE1; close FILE2; close w1; close w2;
i just want to open 2 files and find difference between cond12 and cond22 and if the difference is greater than or equal to some number say 2 print the lines again in 2 different files.
file 1 (1.txt) aqw dfr 34 poilo ggg 98 file 2 (2.txt) qww asd 28 poilo ggg 97
when i try this i am not able to get the output in proper way i mean my output should look like this
3.txt aqw dfr 34 4.txt qww asd 28
it would not print the other lines since the difference is less than 2

Replies are listed 'Best First'.
Re: problem in looping
by kcott (Archbishop) on Aug 13, 2012 at 19:35 UTC

    If you want to compare those files line-by-line, you should lose the second while, i.e.

    while (my $line2 = <FILE2>) {

    should just be

    my $line2 = <FILE2>;

    and, of course, remove the closing brace from the second while block.

    With your code as it is now, you're comparing: 34 with 28 (diff > 2); then 34 with 97 (diff > 2); then 98 with nothing! - you've read all of 2.txt by this point.

    I'd also recommend you take a look at the syntax shown in the first two example statements in the documentation for open.

    -- Ken

Re: problem in looping
by hbm (Hermit) on Aug 13, 2012 at 19:10 UTC

    This should get you close, though it assumes the two input files have the same number of lines.

    use strict; use warnings; my @f1 = get_lines("1.txt"); my @f2 = get_lines("2.txt"); open(my $out1, ">", "3.txt") or die; open(my $out2, ">", "4.txt") or die; for my $i (0..$#f1){ if (abs($f1[$i]->[1]-$f2[$i]->[1])>1){ print $out1 "$f1[$i]->[0]\n"; print $out2 "$f2[$i]->[0]\n"; } } close $out1; close $out2; sub get_lines { my $file = shift; my @lines; open(my $fh, "<", $file) or die("Unable to open $file: $!"); while(<$fh>){ chomp; /(\d+)$/; push @lines, [ $_, $1 ]; } close $fh; return @lines; }
Re: problem in looping
by aitap (Curate) on Aug 13, 2012 at 23:35 UTC

    First of all, use warnings and strict if your script is longer than several lines. It is really a good practice which will help you to avoid many errors.

    Secondly, it is recommended to use more modern and more safe three-argument form of open, using scalar variables as filehandles:

    open my $file1,"<","1.txt" or die "1.txt: $!\n"; open my $file2,"<","2.txt" or die "2.txt: $!\n"; open my $w1,">","3.txt" or die "3.txt: $!\n"; open my $w2,">","4.txt" or die "4.txt: $!\n";
    You can even use autodie to skip writing those checks. You can also pass file names as command-line arguments.

    Thirdly, you can process both files in one while loop, if you want to just check the data of the same line numbers:

    while ( defined(my $line1=<$file1>) and defined(my $line2=<$file2>) ) { if (abs( (split"\t",$line1)[2]-(split"\t",$line2)[2] )>=2) { print $w1 "$line1\n"; print $w2 "$line2\n"; } }

    Fourthly, remember: indenting is your friend. It helps to understand the structure if your program. Run your code through Perl::Tidy, set up your editor to indent the text for you, or install the Perl IDE.

    Note: the code samples are untested and may fail for some reason.

    Sorry if my advice was wrong.