あるファイルのlatとlongの場所を、別のファイルのいくつかの名前付きフィールドに解決しようとしています。
このようなファイルが1つあります。
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。
f3、f4、f5に対応するフィールド11、12、および13を持つ別のはるかに大きなcsvファイルがあります。
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
ファイル2のフィールド11&&12;でファイル1のフィールド1&&2に最も近いものを見つける必要があります。
最も近い一致が見つかったら、ファイル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で変更しました、うまく機能するばかげた1つのライナー.. (より良い方法???)
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
次に、形式を変換する必要があります。(これを解決しました(以下を参照)-問題-数値の四捨五入が多すぎます。小数点以下6桁以上にする必要があります。)
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)+($ 5/3600)) 「%。8f」を追加
printf( "%。8f"、$ 3 +($ 4/60)+($ 5/3600))
次の問題は、フィールドファイル1f3とf4をファイル2f11とf12の最も近い一致に一致させることです。
何か案は?
次に、フィールド間の距離を計算する必要があります。
Excelでは、式は次のようになります。
=ATAN2(COS(lat1)*SIN(lat2)-SIN(lat1)*COS(lat2)*COS(lon2-lon1), SIN(lon2-lon1)*COS(lat2))
その計算には何を使用できますか?
*更新---私は一致する場所の短い距離を見ています。ピタゴラスの定理のような単純なものを最も近い一致に適用することを考えていました。たぶん、小数点以下の桁数を減らすことさえできます。それは何倍も速くなければなりません。多分このようなもの.. *
x = (lon2-lon1) * Math.cos((lat1+lat2)/2);
y = (lat2-lat1);
d = Math.sqrt(x*x + y*y) * R;
次に、最終ファイルが更新された後、精度を高めるために必要な重い計算を行うことができます。
ありがとう