user3389597
user3389597

Reputation: 471

Awk subtract many columns between two files

If I have two files with 4 columns of data in each and I want to subtract columns between these files, I do something like:

paste data1.txt data2.txt | awk '{ printf("%s %d %d %d\n", $1, ($2-$6), ($3-$7), ($4-$8); }' > out.txt

How should I do something similar if I have files with 100 columns each and I want to subract columns between two files without writing so many ($i-$j), ($k-$l), etc.

Thank you.

Upvotes: 3

Views: 468

Answers (3)

Ruud Helderman
Ruud Helderman

Reputation: 11018

Using getline; loosely based on an answer I found here:

awk '{split($0,a);getline<"file2";for(i=1;i<=NF;i++)$i=a[i]-$i;}1' file1

Example:

file1:

31 33 35 37
51 53 55 57

file2:

21 22 23 24
31 32 33 34

output:

10 11 12 13
20 21 22 23

Upvotes: 0

karakfa
karakfa

Reputation: 67507

awk to the rescue!

assuming your file1 has one more column than file2 and you're diffing corresponding columns from file1 and file2

$ paste file1 file2 | 
  awk '{n=int(NF/2); printf "%s", $1; 
        for(i=2;i<=n+1;i++) printf "%d" ,OFS ($i-$(i+n)); printf "\n"}'

it also implicitly assumes total number of fields are odd.

with dummy data

create 100 column file; append row headers to one of them. Since the data portions are equal, all diffs are expected to be zero.

$ seq 200 | xargs -n 100 > file2
$ paste <(echo -e "row1\nrow2") file2 > file1

$ paste file1 file2 | awk ...

row1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
row2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Upvotes: 0

glenn jackman
glenn jackman

Reputation: 246807

Use a loop. You need to pass in the number of columns

awk -v cols=100 '{ 
    printf "%s", $1
    for (i=2; i <= cols; i++)
        printf "%s%d", OFS, $i - $(cols+i)
    printf "\n"
}'

Upvotes: 1

Related Questions