2

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
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.

  • +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 '14 at 3:41
3

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
3

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]'
  • That's clever!!! – user55518 Mar 10 '14 at 6:19
2

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   

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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