Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I want your help in multiplying my data file with another index data file. Both data files have the same number of rows. But the data file have more than 1000 columns while the index data has only one column. The index file is the factor by which I want to multiply the whole columns of the my data. Here is my sample data and the required output below

Data.txt:

10  20  30  40  50
20  30  40  50  60
30  40  50  60  70
40  50  60  70  80
50  60  70  80  90
60  70  80  90  100
70  80  90  100 110
80  90  100 110 120

index.txt:

0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
.
.
.
.

Required output file will be

out.txt

1   2   3   4   5
4   6   8   10  12
9   12  15  18  21
16  20  24  28  32
25  30  35  40  45
36  42  48  54  60
49  56  63  70  77
64  72  80  88  96
share|improve this question

4 Answers 4

Try this:

awk 'FNR==NR{a[FNR]=$0;next}
    {for(i=1;i<=NF;i++){printf("%d\t",$i*a[FNR])}printf("\n")}' index.txt data.txt

For index.txt, we save value of each line in associative array. Then when proccessing data.txt we multiply each fields value with corresponding value in associative array, which is a[FNR].

It works similiar with @devnull's answer but we don't have to hard code file name in our program.

share|improve this answer
    
Thank you, It also works well!! –  Abraham Mar 10 at 5:44
    
+1: You can shorten it by doing awk 'FNR==NR{a[FNR]=$0;next}{for(i=1;i<=NF;i++)$i=$i*a[FNR]}1' OFS='\t' index.txt data.txt –  jaypal singh Mar 11 at 3:41

You could use awk. Read the corresponding line from index.txt while reading data.txt and multiply every field by the value obtained from the former:

awk '{getline f < "index.txt"; for(i=1;i<=NF;i++) {printf("%d\t",$i*f)} printf("\n")}' data.txt

For your input, it'd produce:

1       2       3       4       5
4       6       8       10      12
9       12      15      18      21
16      20      24      28      32
25      30      35      40      45
36      42      48      54      60
49      56      62      70      77
64      72      80      88      96
share|improve this answer
    
Thank you very much. It works perfect. –  Abraham Mar 10 at 5:35

Here's one way:

$ paste index.txt data.txt | 
    awk '{for(i=2;i<=NF;i++){printf "%d\t", $1*$(i)}; print "";}' 
1   2   3   4   5   
4   6   8   10  12  
9   12  15  18  21  
16  20  24  28  32  
25  30  35  40  45  
36  42  48  54  60  
49  56  62  70  77  
64  72  80  88  96  

paste will join the corresponding lines of the file, so the index will be $1 in the awk scriptlet which simply goes through each field and multiplies it by the current value of the index.

A similar, if a bit more idiomatic, approach in Perl:

$ paste index.txt data.txt | perl -lane 'print join "\t",map{$_*$F[0]}@F[1..$#F]'
share|improve this answer
    
Thank you terdon!! –  Abraham Mar 10 at 5:48
    
That's clever!!! –  user55518 Mar 10 at 6:19

Simple perl:

#!/usr/bin/perl

open(INDEX,"$ARGV[0]") or die "$@:$!";
open(DATA,"$ARGV[1]") or die "$@:$!";

while (($dline=<DATA>) and ($i=<INDEX>)) {
  chomp($dline, $i);
  for $n (split /\s+/, $dline) {
    printf "%-4d ", $n * $i;
  }
  print "\n";
}

.

$ perl mult.pl index.txt data.txt
1    2    3    4    5    
4    6    8    10   12   
9    12   15   18   21   
16   20   24   28   32   
25   30   35   40   45   
36   42   48   54   60   
49   56   62   70   77   
64   72   80   88   96   
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.