PDA

View Full Version : Awk multiply values contained in 2 different files



YoYoMoMo
February 22nd, 2013, 03:25 PM
Hi Everyone !

I have two files with the same configuration
and I want to multiply corresponding values and write the result in a file.
Let say 2 header lines and then lines of values (with not constant number of columns):



more file1.txt -->
BLABLABLA
BLABLABLA
1 2 3 4
1 2 3
1 2
1 2 3


more file2.txt -->
BLABLABLA
BLABLABLA
2 2 2 2
2 2 2
1 1
1 1 1
I want to have this results:


more file3.txt -->
BLABLABLA
BLABLABLA
2 4 6 8
2 4 6
1 2
1 2 3

Anyone has an idea ? Thanks in advance,
Y.

schragge
February 22nd, 2013, 03:51 PM
In awk, try to read the contents of each file into its own array, then in the END clause, multiply elements of two arrays in a loop.

Update.
If there were only one column in each file, I'd suggest something like


$ cat file1.txt
15
8
92
53
$ cat file2.txt
96
30
34
86
$ paste -d\* file[12].txt|bc
1440
240
3128
4558

steeldriver
February 22nd, 2013, 03:57 PM
Hello and welcome

You could also try a 'while... read' loop in bash instead of awk


while read -u3 -a vals1; read -u4 -a vals2
do
your math on the array values
done 3< file1.txt 4< file2.txtThere may be a neater way to do it with an associative array instead of separate arrays for the two file inputs

YoYoMoMo
February 22nd, 2013, 05:07 PM
Thanks a lot for your answers.
This is a good basis for the beginning of my program.

ofnuts
February 23rd, 2013, 12:19 AM
http://stackoverflow.com/questions/11160145/merge-two-files-in-linux-with-different-column

steeldriver
February 23rd, 2013, 12:35 AM
I kind of assumed this was homework, but if not


while read -u3 -a line1; read -u4 -a line2
do
for (( i=0; i< ${#line1[@]}; i++ ))
do printf "%d " $(( ${line1[i]} * ${line2[i]} ))
done
printf "\n"
done 3< file1.txt 4< file2.txt
0
0
2 4 6 8
2 4 6
1 2
1 2 3
The extra zeros are because I didn't bother to strip the header lines, probably extra credit to be had for checking that the ith value of the second array exists as well

Vaphell
February 23rd, 2013, 03:16 PM
in case of awk i'd try something like this:

paste file1 file2 | awk '{ for(i=1;i<=NF/2; i++) printf("%d ", $i*$(i+NF/2)); printf("\n"); }'
paste to put columns next to each other, and then in awk for every row multiply i-th element by (i+NF/2)-th element

YoYoMoMo
March 6th, 2013, 12:26 PM
Thanks a lot Vaphell, it works very well !
I have just added a if condifition because of the header.



paste $filein1 $filein2 | awk ' BEGIN {begdata=0}{
if ((NR>2 && NF==12) || begdata==1) {
for(i=1;i<=NF/2;i++) {
printf(" %12.5E",$i*$(NF/2+i));
}
printf("\n");
begdata=1;
}
else
{
print substr($0,0,length($0)/2)
}
}' > $fileout

schragge
March 6th, 2013, 01:29 PM
Well, I guess to get rid of headers, this would be enough:

head -2 file1; paste file{1,2} | awk 'NR>2 {c=NF/2; for(i=0;i++<c;) printf "%d%s", $i*$(i+c), i<c?" ":"\n"}'