データベースを使用してIPアドレスを座標に変換する

データベースを使用してIPアドレスを座標に変換する

IPを含むファイルがあり、それをローカルデータベース(APIではない)を使用して座標と比較したいと思います。

私はプロセスに従い、それを細分化し、さまざまな記事を参照するスクリプトを作成しようとしています。

座標データベースファイル:

16777216 16777471 AU Australia Queensland Brisbane -27.467940 153.028090
16777472 16778239 CN China Fujian Fuzhou 26.061390 119.306110
16778240 16779263 AU Australia Victoria Melbourne -37.814000 144.963320
16779264 16781311 CN China Guangdong Guangzhou 23.116670 113.250000

IPアドレスファイル:

131.72.136.65
131.72.138.204
131.72.138.45
131.72.139.112
131.72.139.163

そのため、まず比較できるようにIPを10進数に変更しました。

IP2Dec

#!/bin/bash
# while read line; do echo  "$line"; done < iplist.txt
ip2dec () {
    local a b c d ip=$@
    IFS=. read -r a b c d <<< "$ip"
    printf '%d\n' "$((a * 256 ** 3 + b * 256 ** 2 + c * 256 + d))"
}

ip2dec "$@"

IPとDBファイルを比較し、以下のスクリプトを使用してIP、緯度、経度を印刷しました。

awk 'NR == FNR { x[$1] = $1+0; next; } { for (i in x) { if (x[i] > $1+0 && x[i] < $2+0) { print x[i], $NF-1, $NF;} } }' ip.txt db.txt

これで出力は次のようになります。

387306133 -78.4875 -77.487490
399341146 -105.985 -104.984700
399478903 -105.985 -104.984700
401285510 -123.395 -122.395200
401289024 -123.395 -122.395200
520966134 102.85 103.850070

今度は10進数を再びIPアドレスに変換したいと思います。

    #!/bin/bash
dec2ip () {
    local ip dec=$@
    for e in {3..0}
    do
        ((octet = dec / (256 ** e) ))
        ((dec -= octet * 256 ** e))
        ip+=$delim$octet
        delim=.
    done
    printf '%s\n' "$ip"
}
    dec2ip "$@"

しかし、これはファイル全体を変換するので、最初の列だけを変換し、LadとLonを維持したいと思います。

私はこれらすべてを一つにまとめて一つの作品を作ろうとします。

また、これが有効なアプローチですか?結局、私はこのIPをGoogleマップに表示したいと思います。

ベストアンサー1

IP2Decスクリプトとdec2ipスクリプト(ファイルの一部でのみ実行する必要があります)を除いて機能する必要があります。以下は、行の最初の項目にのみ関数を適用するdec2ipの例です。

#!/bin/bash
dec2ip () {
        local ip dec=$@
        delim=""
        for e in {3..0}
        do
                ((octet = dec / (256 ** e) ))
                ((dec -= octet * 256 ** e))
                ip+="$delim$octet"
                delim=.
        done
        printf '%s' "$ip"
}

while read IP lon lat ; do
        dec2ip $IP
        printf " %s %s\n" "$lon" "$lat"
done

より良いアプローチは、すべてを高度な言語で短い方法で書くことです。次のPython 2.7スクリプトは必要なタスクを実行する必要があります(速度に最適化されていません)。

#!/usr/bin/python   
import socket,struct
db=[]
for l in open("db.txt"):
    fields=l.split();
    db.append((int(fields[0]),int(fields[1]),fields[-2],fields[-1]))

for l in open("ip.txt"):
    ip=struct.unpack('!I',socket.inet_aton(l))[0]
    for e in db:
        if e[0]<=ip<=e[1]:
            print l.strip(),e[2],e[3]
            break

おすすめ記事