我有一个data.txt文件
1 2 3 4 5 6 7
cat data.txt
13 245 1323 10.1111 10.2222 60.1111 60.22222
13 133 2325 11.2222 11.333 61.2222 61.3333
13 245 1323 12.3333 12.4444 62.3333 62.44444444
13 245 1323 13.4444 13.5555 63.4444 63.5555
查找下一个最接近的内容:我的目标值为11.6667
,它应该在column 4
中找到最近的下一个值12.3333
查找上一个最近的内容:我的目标值为62.9997
,它应该在column 6
中找到最近的前一个值62.3333
我能够通过
找到下一个最近的(案例1)awk -v c=4 -v t=11.6667 '{a[NR]=$c}END{
asort(a);d=a[NR]-t;d=d<0?-d:d;v = a[NR]
for(i=NR-1;i>=1;i--){
m=a[i]-t;m=m<0?-m:m
if(m<d){
d=m;v=a[i]
}
}
print v
}' f
12.3333
任何bash解决方案?找到最近的(案例2)?
答案 0 :(得分:1)
第一部分:
awk -v v1="11.6667" '$4>v1 {print $4;exit}' file
12.3333
第二部分:
awk -v v2="62.9997" '$6>v2 {print p;exit} {p=$6}' file
62.3333
一气呵成:
awk -v v1="11.6667" -v v2="62.9997" '$4>v1 && !p1 {p1=$4} $6>v2 && !p2 {p2=p} {p=$6} END {print p1,p2}' file
12.3333 62.3333
答案 1 :(得分:1)
试试这个:
$ cat tst.awk
{
if ($fld > tgt) {
del = $fld - tgt
if ( (del < minGtDel) || (++gtHit == 1) ) {
minGtDel = del
minGtVal = $fld
}
}
else if ($fld < tgt) {
del = tgt - $fld
if ( (del < minLtDel) || (++ltHit == 1) ) {
minLtDel = del
minLtVal = $fld
}
}
else {
minEqVal = $fld
}
}
END {
print (minGtVal == "" ? "NaN" : minGtVal)
print (minLtVal == "" ? "NaN" : minLtVal)
print (minEqVal == "" ? "NaN" : minEqVal)
}
$ awk -v fld=4 -v tgt=11.6667 -f tst.awk file
12.3333
11.2222
NaN
$ awk -v fld=6 -v tgt=62.9997 -f tst.awk file
63.4444
62.3333
NaN
$ awk -v fld=6 -v tgt=62.3333 -f tst.awk file
63.4444
61.2222
62.3333
答案 2 :(得分:0)
您的解决方案看起来不必要地复杂化(存储整个数组并对其进行排序),如果您重新考虑bash
,我认为您会看到awk
解决方案。
在awk
中,您可以使用
FNR==1 {do something}
所以在第一行,将变量BestYet
设置为您要搜索的列中的值。
在后续行中,只需测试您正在检查的列中的值是否为
a) less than your target AND
b) greater than `BestYet`
如果是,请更新BestYet
。最后,打印BestYet
。
在bash
中,应用相同的逻辑,但将每行读入bash数组并使用${a[n]}
来获取第n个元素。
答案 3 :(得分:0)
我不知道这是不是你想要的,但这就是我想出来的,不知道awk
:
#!/bin/sh
IFSBAK=$IFS
IFS=$'\n'
best=
for line in `cat $1`; do
IFS=$' \t'
arr=($line)
num=${arr[5]}
[[ -z $best ]] && best=$num
if [ $(bc <<< "$num < 62.997") -eq 1 ]; then
if [ $(bc <<< "$best < $num") -eq 1 ]; then
best=$num
fi
fi
IFS=$'\n'
done
IFS=$IFSBAK
echo $best
如果需要,可以添加列和输入值62.997
作为参数,我没有证明它会特意查找您想要的内容。
编辑以删除文件已排序的假设。