我正在尝试将一个文件中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 char 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;
然后,我可以在更新最终文件后进行更高精度所需的繁重计算。
由于
答案 0 :(得分:0)
执行最接近的匹配后,您无法进行距离计算:通过比较距离值来定义最近距离。 Awk可以评估你想要的公式(看起来像大圆距离?)。看看this chapter,看看你需要什么。
最大的问题是找到最近的匹配。编写一个awk脚本,它接受一行文件1并输出文件2中的行和一个额外的列。该列是根据您的距离公式计算这对点之间的距离。如果您以数字方式对该文件进行排序(sort -n
),那么您最接近的匹配位于顶部。然后你需要一个循环遍历文件1中每一行的脚本,调用你的awk脚本,使用head -n1
拉出最接近的匹配,然后以你想要的格式输出它。
这在bash和awk中都是可能的,但在Python中它将是一个更简单的脚本。取决于你喜欢的。