Reputation: 121
I would like to have a way to filter one file accordingly to another file, but considering different ranges for each file as the number are different and the names for column 1 are different too. So for example columns 2 and 4 could vary in a range of 50 while columns 3 and 5 for 0.05 and 0.005, respectively.
file 1
ddd 10 2 0.3 4 0.02
ccc 250 22 0.2 2 0.04
aaa 10 10 0.10 10 0.02
xxx 12 12 0.12 2 0.01
showman 150 15 0.15 200 0.003
porco 15 100 0.15 15 12
file 2
super 120 11 0.12 150 0.005
output
showman 150 15 0.15 200 0.003
Upvotes: 1
Views: 158
Reputation: 19760
This is similar to Simon's solution, but it avoids calling awk twice.
function abs(x) {return ((x < 0.0) ? -x : x)}
BEGIN {
tol[2]=50
tol[3]=5
tol[4]=0.05
tol[5]=50
tol[6]=0.005
}
FNR==NR {
for (i=2; i<=NF; i++)
target[i]=$i
}
FNR < NR {
for (i=2; i<=NF; i++)
if (abs($i - target[i]) > tol[i])
next
print
}
Call using awk -f match.awk file2 file1
Upvotes: 2
Reputation: 10841
The following shell script, which I've called filterrange
, generates an awk
script filterrange.awk
from file2.txt
and then runs that awk
script to do the filtering:
#!/bin/sh
awk 'BEGIN { r[2] = 50; r[3] = 5; r[4] = 0.05; r[5] = 50; r[6] = 0.005 }
{ print "function abs(x){return ((x < 0.0) ? -x : x)}"
for (i = 2; i <= NF; i++) {
printf("abs($%s-%s)<=%s", i, $i, r[i])
if (i < NF) printf(" && ")
}
}' <$1 >filterrange.awk
awk -f filterrange.awk <$2
The abs()
function is from Absolute value in awk doesn't work?.
Running this shell script gives the following result:
$ filterrange file2.txt file1.txt
showman 150 15 0.15 200 0.003
The range tolerances are fixed in the template awk
script shown here but they could be easily generated from a separate file using a similar approach, if required.
Upvotes: 1