0

I am stuck in middle , i need help .

i have two files :

  • file1:

Total X :
Total y :
Total z :
Total t :

file 2:
4790351 4786929 3422 0
84860 84860 0 0
206626 206626 0 0
93902 93823 79 0

now i want output like this in third file

Total X : 4790351 4786929 3422 0
Total y : 84860 84860 0 0
Total z : 206626 206626 0 0
Total t : 93902 93823 79 0

This is my code below to try the parsing :Please help me getting the required output

while ( not eof $tata and not eof $outfh )
 {
   my @vals1 = split /":"/,<$tata>;


   my @vals2 = split /\s+/, <$outfh>;

   my @sum = join "\t", map { $vals1,$vals2[$_]} 0 .. $#vals2;

   printf $_ for @sum,"\n";

   }
0

2 Answers 2

1
use strict;
use warnings; 
use 5.020;
use autodie;
use Data::Dumper;

open my $FILE1, "<", "file1.txt";
open my $FILE2, "<", "file2.txt";
open my $OUTFILE, ">", "results.txt";

my $first_line = <$FILE1>;
close $FILE1;

my @line_prefixes = split /\s*:\s*/, $first_line;

while (my $line = <$FILE2>) {
    print {$OUTFILE} "$line_prefixes[$. - 1]: $line";
}

close $FILE2;
close $OUTFILE;

$. is the current line number in the file ($. equals 1 for the first line).

A sample run:

/pperl_programs$ cat file1.txt
Total X : Total y : Total z : Total t :

~/pperl_programs$ cat file2.txt
4790351 4786929 3422 0
84860 84860 0 0
206626 206626 0 0
93902 93823 79 0

~/pperl_programs$ cat results.txt

~/pperl_programs$ perl myprog.pl

~/pperl_programs$ cat results.txt
Total X: 4790351 4786929 3422 0
Total y: 84860 84860 0 0
Total z: 206626 206626 0 0
Total t: 93902 93823 79 0
~/pperl_programs$ 

For your altered files:

use strict;
use warnings; 
use 5.020;
use autodie;
use Data::Dumper;

open my $FILE1, "<", "file1.txt";
open my $FILE2, "<", "file2.txt";
open my $OUTFILE, ">", "results.txt";

chomp(my @line_prefixes = <$FILE1>);
close $FILE1;

while (my $line = <$FILE2>) {
    print {$OUTFILE} "$line_prefixes[$.-1] $line";
}

close $FILE2;
close $OUTFILE;

Sample output:

~/pperl_programs$ cat file1.txt
Total X :
Total y :
Total z :
Total t :

~/pperl_programs$ cat file2.txt
4790351 4786929 3422 0
84860 84860 0 0
206626 206626 0 0
93902 93823 79 0

~/pperl_programs$ cat results.txt

~/pperl_programs$ perl 1.pl

~/pperl_programs$ cat results.txt
Total X : 4790351 4786929 3422 0
Total y : 84860 84860 0 0
Total z : 206626 206626 0 0
Total t : 93902 93823 79 0

If your files are big, you probably don't want to read the whole first file into memory. If that's the case, you can read each file line by line:

use strict;
use warnings; 
use 5.020;
use autodie;
use Data::Dumper;

open my $FILE1, "<", "file1.txt";
open my $FILE2, "<", "file2.txt";
open my $OUTFILE, ">", "results.txt";

while (!eof($FILE1) and !eof($FILE2) ) {
    my $line_prefix = <$FILE1>;
    chomp $line_prefix;

    my $numbers_line = <$FILE2>;
    chomp $numbers_line;
    my @numbers = split /\s+/, $numbers_line;

    my $fifth_column = $numbers[1] / $numbers[0];
    say {$OUTFILE} "$line_prefix $numbers_line $fifth_column";
}

close $FILE1;
close $FILE2;
close $OUTFILE;
Sign up to request clarification or add additional context in comments.

6 Comments

Hi stud ...actually file 1 don't have all labels in single line .... Total x then Total y in new line and so on....So your code is printing first line of file 1 till first split
@Volverine, I added an example for your new input files.
@stud ..thanks it worked ...i have one more query ... suppose i want to divide column 2 value with value column value 3 and print it in last column new to add (5th column) ..how can we do that...for example Total X : 4790351 4786929 3422 0 0.99 ( same for rest too ). can you please help for that too
@Volverine, Illegal division by zero. But generally, my @numbers = split /\s+/, $line; my $fifth_column = $numbers[1] / $numbers[2]; print {$OUTFILE} "$line_prefixes[$.-1] $line $fifth_column";
@stud my output is coming like below Total Z : 2135943 2135943 0 0 Total Y : 420512 420512 0 0 Total X : 0 0 0 0 can we allign the output like below Total Z : 2135943 2135943 0 0 Total Y : 420512 420512 0 0 Total X : 0 0 0 0
|
0

Your specification has a few loose ends; for instance - what if there are more lines in file2 then there are total labels in file1? Do you want the spaces in the first input file ignored? Do you want the spaces in the output file specifically as shown? ... and you really don't want any totals calculated??

I've presumed "yes" to most of these questions. My solution is driven by the second data file - which means that if there are more total labels then there are lines of data, they are going to be ignored. It also means that if there are more data lines in file2 then there are labels in file1, the program will simply make up the label - No Label?.

Finally, just in case you want to add these numbers up at some point, I've included but commented the sum function from List::Util.

use v5.12;
use File::Slurp;
# use File::Util qw( sum );

my $file1 = "file1.txt";
my $file2 = "file2.txt";
my $file3 = "file3.txt";

open(my $outfh, '>', $file3) or die "$file3: $!";

my @vals1 = split /\s*:\s*\n/ , read_file($file1);
my @vals2 = read_file($file2);

while (my $line = shift @vals2) {
    chomp $line;
    # my $total = sum split(" ", $line);
    printf $outfh  "%s : %s\n" , shift @vals1 // "No Label?" , $line ;
}
#
# $ cat file3.txt
Total X : 4790351 4786929 3422 0
Total y : 84860 84860 0 0
Total z : 206626 206626 0 0
Total t : 93902 93823 79 0

2 Comments

there will always we equal num of labels and data in both files
Then the code shown will work fine - it only requires the // "No Label?" to cover the error condition so, might as well leave it there.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.