我试图在一个文件中将lat和long中的位置解析为另一个文件中的几个命名字段。比较最近匹配的两个文件中的字段
我有一个文件,它是这样的..
f1--f2--f3--------f4-------- f5---
R 20175155 41273951N078593973W 18012
R 20175156 41274168N078593975W 18000
R 20175157 41274387N078593976W 17999
R 20175158 41274603N078593977W 18024
R 20175159 41274823N078593978W 18087
每个字符是在一个特定的地方,所以我需要定义基于字符的字段。
f1 char 18-21; f2 char 22 - 25; f3 char 26-35; f4 char 36-45; f5字符62-66。
我有另一个更大的csv文件,其中有11,12和13字段对应于f3,f4,f5。
awk -F',' '{print $11, $12, $13}'
41.46703821 -078.98476926 519.21
41.46763555 -078.98477791 524.13
41.46824123 -078.98479015 526.67
41.46884129 -078.98480615 528.66
41.46943371 -078.98478482 530.50
我需要找到最匹配的文件1场1 & & 2文件2场11 & & 12;
当最接近的匹配被发现我需要从文件1插入字段1,2,3,4,5到文件2字段16,17,18,19,20
正如可以看到格式略有不同。文件1个发生故障这样的..
文件1个
f3-------f4--------
DDMMSSdd DDDMMSSdd
41273951N078593973W
文件2
f11-------- f12---------
DD dddddddd DDD dddddddd
41.46703821 -078.98476926
N表示f3是一个正数,W表示f4是一个负数。
我改变文件1 SED,雷人的内衬的伟大工程.. (更好的办法???)
cat $file1 |sed 's/.\{17\}//' |sed 's/\(.\{4\}\)\(.\{4\}\)\(.\{9\}\)\(.\)\(.\{9\}\)\(.\)\(.\{16\}\)\(.\{5\}\)/\1,\2,\3,\4,\5,\6,\8/'|sed 's/\(.\{10\}\)\(.\{3\}\)\(.\{2\}\)\(.\{2\}\)\(.\{2\}\)\(.\{3\}\)\(.\{3\}\)\(.\{2\}\)\(.*\)/\1\2,\3,\4.\5\6\7,\8\9/'|sed 's/\(.\{31\}\)\(.\{2\}\)\(.*\)/\1,\2.\3/'
2017,5155,41,27,39.51,N,078,59 ,39.73,W,18012
2017,5156,41,27,41.68,N,078,59,39.75,W,18000
2017,5157,41,27,43.87,N,078,59,39.76,W ,17999
2017,5158,41,27,46.03,N,078,59,39.77,W,18024
2017,5159,41,27,48.23,N,078,59,39.78,W,18087
现在我必须转换格式.. (已解决此问题(见下文) - 问题 - 数字四舍五入太远。我需要有至少六个小数位)
awk -F',' '{for (i=1;i<=NF;i++) {if (i <= 2) printf ($i","); else if (i == 3&&$6 == "S") printf("-"$3+($4/60)+($5/3600)","); else if (i == 3&&$6 == "N") printf($3+($4/60)+($5/3600)","); else if (i == 7&&$10 == "W") printf("-"$7+($8/60)+($9/3600)","); else if (i == 7&&$10 == "E") printf($7+($8/60)+($9/3600)","); if (i == 11) printf ($i"\n")}}'
2017,5155,41.461,-78.9944,18012
2017,5156,41.4616,-78.9944,18000
2017,5157,41.4622, - 78.9944,17999
2017,5158,41.4628,-78.9944,18024
2017,5159,41.4634,-78.9944,18087
这是我在哪里。
解决了这个 * 我需要的数字格式有从这个公式至少6位小数。 *
的printf($ 3 +($ 4/60)+($3600分之5)) 添加 “%.8f”
的printf( “%8F”,$ 3 +($ 4/60 )+($ 5/3600))
下一期将与匹配字段文件1 f3和f4到文件2中最接近匹配的f11和f12。
有什么建议吗?
然后我将需要计算字段之间的距离。
在Excel中formuls会是这样..
=ATAN2(COS(lat1)*SIN(lat2)-SIN(lat1)*COS(lat2)*COS(lon2-lon1), SIN(lon2-lon1)*COS(lat2))
我可以用什么来该计算?
* UPDATE --- 我正在寻找匹配位置的短距离。我正在考虑应用像毕达哥拉斯定理那样简单的东西来进行最接近的比赛。也许甚至使用更少的小数位。它的速度要快很多倍。 也许是这样的.. *
x = (lon2-lon1) * Math.cos((lat1+lat2)/2);
y = (lat2-lat1);
d = Math.sqrt(x*x + y*y) * R;
然后最终文件被更新后,我可以做更大的精度所需的大量计算。
感谢
我不认为你可以用'awk'获得你需要的精度。但是,'bc'应该提供“任意精度”以及一个好的几何函数库。我建议你将问题分为“如何规范化这两种文件格式”和“如何在数字在文件中时用'bc'进行计算”。也许你已经可以自己解决这两个问题了。 – tripleee 2012-07-08 08:17:53
也许这篇文章可以帮助:http://www.linuxjournal.com/magazine/work-shell-calculating-distance-between-two-latitudelongitude-points – user1498339 2012-07-08 08:25:56
@tripleee:在AWK中查看'OFMT'和'CONVFMT'变量。你不能像'bc'那样得到任意的精度,但你肯定可以为这个应用程序获得足够的小数位数。 – 2012-07-08 10:45:47