问题
I have two different files. Part of those files are:
file 1:
ifile1.txt
21 10.3 70.32 09
32 11.3 71.43 10
33 15.4 75.00 00
54 17.3 68.03 12
95 19.2 65.02 21
99 20.1 80.10 11
and so on......
Where 1st column is the ID,
2nd column refers to x-axis,
3rd column refers to y-axis,
4th column refers to value
file2:
ifile2.txt
10.10 70.12 10
10.11 73.33 08
11.05 72.40 00
11.30 69.13 15
12.00 64.02 27
12.05 79.20 25
13.10 80.32 10
13.11 75.43 06
14.05 74.00 02
14.20 69.03 15
16.40 65.02 13
16.55 68.10 14
and so on......
Where 1st column refers to x-axis,
2nd column refers to y-axis,
3rd column refers to value
I would llike to make another file whose output will be (for the above example):
ofile.txt
21 10.10 70.12 10
32 11.05 71.40 10
33 14.05 74.00 02
54 16.55 68.10 14
95 16.55 68.10 14
99 16.55 68.10 14
Where 1st column is the ID (taken from ifile1.txt),
2nd and 3rd column refers to x-axis and y-axis (taken from ifile2.txt which are the nearest to those of ifile1.txt),
4th column refers to corresponding value (taken from ifile2.txt)
I can't able to write a shell script for this. However my algorithm is:
for each $1 in ifile1.txt,
for each $2 & $3 in ifile1.txt,
find a $2 & $3 in ifile2.txt such that
sqrt{[$2(ifile1.txt)-$2(ifile2.txt)]^2+[$3(ifile1.txt)-$3(ifile2.txt)]^2} is minimum for all $2 & $3 in ifile2.txt
find correcsponding $4 from ifile2.txt
write $1, $2, $3, $4 to ofile.txt
I highly appreciate for any kind of suggestions or help.
回答1:
Here is a simple solution in awk. It worked fine at my Linux. If my answer was useful for you please click the grey tick sign on the left side of my answer.
#!/bin/bash
(($#!=2))&& { echo "Usage $0 1st_file 2nd_file"; exit 1; }
awk '
BEGIN {p=fx=0; fn=""; maxd=1.1e11;}
$0~"[^0-9. \t]" || NF!=4 && NF!=3 {next;} # skip no data lines
fn!=FILENAME {fx++; fn=FILENAME;} # fx: which file
fx==1 { if(NF!=3){printf("Change the series of two input files\n"); exit 1;}
x2[p]=$1; y2[p]=$2; d2[p++]=$3;next;} # save the columns of first file
fx==2 { mv=maxd; mp=0; # search minimal distance
for(i=0; i<p; i++){
dx=x2[i]-$2; dy=y2[i]-$3; dd=dx*dx+dy*dy;
if(dd<mv){mv=dd; mp=i;} # min value & min place
}
printf("%3d %6.2f %6.2f %3d\n", $1, x2[mp], y2[mp], d2[mp]);
}
' $2 $1 # first is the 2nd_file!
回答2:
My take on this problem would be the following:
awk '(NR==FNR) { index[FNR]=$1; coordx[FNR]=$2; coordy[FNR]=$3; val[FNR=$4]; next }
{ for(i in index) {
d2=(coordx[i]-$1)*(coordx[i]-$1) + (coordy[i]-$2)*(coordy[i]-$2)
sol[i] = (i in sol ? (min_dist[i] > d2 ? $0 : sol[i]) : $0 )
min_dist[i] = (sol[i] == $0 ? d2 : min_dist[i])
}
END { for(i in index) { print index[i], sol[i] } }
' file1 file2
来源:https://stackoverflow.com/questions/36710230/how-to-find-grid-points-nearest-to-given-location-using-shell-script