1

我想有一种方法可以将一个文件相应地过滤到另一个文件,但考虑到每个文件的不同范围,因为数量不同并且第 1 列的名称也不同。因此,例如,第 2 列和第 4 列可以在 50 范围内变化,而第 3 列和第 5 列分别为 0.05 和 0.005。

文件 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

文件 2

super   120 11  0.12    150 0.005

输出

showman 150 15  0.15    200 0.003
4

2 回答 2

2

这类似于 Simon 的解决方案,但它避免了两次调用 awk。

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
}

调用使用awk -f match.awk file2 file1

于 2015-08-26T05:49:48.740 回答
1

下面的 shell 脚本(我称之为filterrange)生成一个awk脚本filterrange.awkfile2.txt然后运行该awk脚本进行过滤:

#!/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

abs()函数来自awk中的绝对值不起作用?.

运行这个 shell 脚本会得到以下结果:

$ filterrange file2.txt file1.txt
showman 150 15  0.15    200 0.003

范围公差在awk此处显示的模板脚本中是固定的,但如果需要,可以使用类似的方法从单独的文件轻松生成它们。

于 2015-08-26T04:50:13.480 回答