2016-12-08 5 views
0

У меня есть большой файл, который содержит 2 IPs за строку - и всего около 3 миллионов строк.Пакетное преобразование IP-адресов в десятичные числа?

Вот пример файла:

1.32.0.0,1.32.255.255 
5.72.0.0,5.75.255.255 
5.180.0.0,5.183.255.255 
222.127.228.22,222.127.228.23 
222.127.228.24,222.127.228.24 

Мне нужно преобразовать каждый IP к IP Decimal, как это:

18874368,18939903 
88604672,88866815 
95682560,95944703 
3732923414,3732923415 
3732923416,3732923416 

Я предпочел бы способ сделать это строго с помощью команды линия. Я согласен с perl или python, если он не требует установки дополнительных модулей.

Мне показалось, что я столкнулся с тем, что кто-то конвертировал IPs вот так, используя sed, но больше не может найти этот учебник. Любая помощь будет оценена по достоинству.

+0

См. [function ip2dec] (http://stackoverflow.com/a/35681431/3776858). – Cyrus

+0

http://stackoverflow.com/questions/10768160/ip-address-converter – Praveen

ответ

2

Здесь он python решение, что использовать только стандартные модули (Р.Е., SYS):

import re 
import sys 

def multiplier_generator(): 
    """ Cyclic generator of powers of 256 (from 256**3 down to 256**0) 
     The mulitpliers tupple could be replaced by inline calculation 
    of power, but this approach has better performance. 
    """ 
    multipliers = (
     256**3, 
     256**2, 
     256**1, 
     256**0, 
    ) 
    idx = 0 
    while 1 == 1: 
     yield multipliers[idx] 
     idx = (idx + 1) % 4 

def replacer(match_object): 
    """re.sub replacer for ip group""" 
    multiplier = multiplier_generator() 
    res = 0 
    for i in xrange(1,5): 
     res += multiplier.next()*int(match_object.group(i)) 
    return str(res) 

if __name__ == "__main__": 
    std_in = "" 
    if len(sys.argv) > 1: 
     with open(sys.argv[1],'r') as f: 
      std_in = f.read() 
    else: 
     std_in = sys.stdin.read() 
    print re.sub(r"([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)", replacer, std_in) 

Это решение заменить каждый IP-адрес, который можно найти в тексте из стандартного ввода или из файла передается в качестве первого параметр, а именно:

  • питон convert.py < input_file.txt или
  • питон convert.py file.txt или
  • эхо "1.2.3.4, 5.6.7.8" | python convert.py.
+0

Спасибо за ваш ответ! Где в вашем скрипте я должен указать, что мне нужно, чтобы это выполнялось на 'test.txt'? –

+0

Он делает именно то, что я хочу, но что-то похоже на математику. Если вы попробуете запустить мои примеры IP-адресов выше через ваш скрипт, он дает разные IP-десятичные разряды:/ –

+0

Удивительная работа! Благодаря! –

3

Если гну AWK установлен (для переменной RT), вы можете использовать этот Однострочник:

awk -F. -v RS='[\n,]' '{printf "%d%s", (($1*256+$2)*256+$3)*256+$4, RT}' file 
18874368,18939903 
88604672,88866815 
95682560,95944703 
3732923414,3732923415 
3732923416,3732923416 
+0

Все в порядке и имеет лучшую производительность, но оно отображает IP в научном формате. –

+0

@MarekNowaczyk: Это странно, в моей системе выход похож на выше (я копирую с терминала). Мой awk - GNU Awk 4.1.3. Какую версию ты используешь? Попробуйте с '"% d% s "' в качестве строки формата ... – user000001

+1

% d% s формат выполняет эту работу. –

1

С Баш:

ip2dec() { 
    set -- ${1//./ }  # split $1 with "." to $1 $2 $3 $4 
    declare -i dec  # set integer attribute 
    dec=$1*256*256*256+$2*256*256+$3*256+$4 
    echo -n $dec 
} 

while IFS=, read -r a b; do ip2dec $a; echo -n ,; ip2dec $b; echo; done < file 

Выход:

 
18874368,18939903 
88604672,88866815 
95682560,95944703 
3732923414,3732923415 
3732923416,3732923416 
0

С bash и использованием сдвига (одна команда процессора) вместо множителя (много инструкций):

ip2dec() { local IFS=. 
      set -- $1  # split $1 with "." to $1 $2 $3 $4 
      printf '%s' "$(($1<<24+$2<<16+$3<<8+$4))" 
     } 

while IFS=, read -r a b; do 
    printf '%s,%s\n' "$(ip2dec $a)" "$(ip2dec $b)" 
done < file 

 Смежные вопросы

  • Нет связанных вопросов^_^