我試圖在一個文件中將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