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 Answers 4

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
  • +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 Mar 11, 2014 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
0
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]'
1
  • That's clever!!!
    – user55518
    Mar 10, 2014 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   

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .