根据另一列文件中的一系列值相应地按每一列过滤文件
Have a file filtered by each column accordingly with a range of values from another columns file
我想有一种方法可以将一个文件相应地过滤到另一个文件,但考虑到每个文件的范围不同,因为数量不同,第 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
下面的 shell 脚本,我称之为 filterrange
,从 file2.txt
生成一个 awk
脚本 filterrange.awk
,然后运行那个 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(" && ")
}
}' < >filterrange.awk
awk -f filterrange.awk <
abs()
函数来自 Absolute value in awk doesn't work?。
运行 这个 shell 脚本给出以下结果:
$ filterrange file2.txt file1.txt
showman 150 15 0.15 200 0.003
范围公差在此处显示的模板 awk
脚本中是固定的,但如果需要,可以使用类似的方法从单独的文件轻松生成它们。
这与 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
调用
我想有一种方法可以将一个文件相应地过滤到另一个文件,但考虑到每个文件的范围不同,因为数量不同,第 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
下面的 shell 脚本,我称之为 filterrange
,从 file2.txt
生成一个 awk
脚本 filterrange.awk
,然后运行那个 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(" && ")
}
}' < >filterrange.awk
awk -f filterrange.awk <
abs()
函数来自 Absolute value in awk doesn't work?。
运行 这个 shell 脚本给出以下结果:
$ filterrange file2.txt file1.txt
showman 150 15 0.15 200 0.003
范围公差在此处显示的模板 awk
脚本中是固定的,但如果需要,可以使用类似的方法从单独的文件轻松生成它们。
这与 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