3

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.

user3389597
  • 451
  • 2
  • 10

3 Answers3

1

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"
}'
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
0

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
karakfa
  • 66,216
  • 7
  • 41
  • 56
0

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
Ruud Helderman
  • 10,563
  • 1
  • 26
  • 45