Формирование IPAddresses от Текстового файла

У меня есть огромный текстовый файл, который содержит IP-адреса, скремблированные на всем протяжении, но не в одной единице

например.

Таким образом, какие the@192 heck являются Вами doing@168 в моем доме @10. Вы не были @16 предположены быть здесь.

То, что я хочу, должно сделать выходной файл, и в этом делают ipadresses файл как следующее

    1.192.168.10.16
    2.192.223.22.44
    etc..

Я имею хорошее понимание регулярных выражений и могу извлечь определенную информацию из текстового файла, но здесь я должен объединить их это, где я запутался. Как нужно приблизиться к проблеме как этот? Я использую Ubuntu 12.04.

1
задан 13 April 2014 в 17:39

3 ответа

Самый простой подход, о котором я могу думать, предполагая, что числа Вы хотите, всегда разграничивается @ символы:

$ grep -oP '@\K\d+' file | perl -pe '$. % 4 != 0 && s/\n/./;'
192.168.10.16
192.169.10.16
192.128.10.16
192.162.10.16

Это не нумерует строки, хотя, так для добавления их делают

$ grep -oP '@\K\d+' file | perl -pe '$. % 4 != 0 && s/\n/./;' | perl -pe 's/^/$.. /'
1. 192.168.10.16
2. 192.169.10.16
3. 192.128.10.16
4. 192.162.10.16

Объяснение

  • grep -oP '@\K\d+' file : -o означает "печать только часть соответствия строки" и -P включает Perl совместимые регулярные выражения (PCRE) для grep. Это позволяет нам использовать \d соответствовать числам и, самое главное, \K что означает, "забывают то, чему Вы соответствовали передо мной". \K позволяет мне grep для @\K10 и только печать 10 потому что @ перед \K.
  • perl -pe : считайте входной файл линию за линией, примените сценарий, данный -e к каждой строке и затем печатают ту строку (-p).
  • '$. % 4 != 0 && s/\n/./; : % оператор по модулю, $. текущий номер строки входного файла. Этот код заменит новой строкой charatcer (\n) с a . на строках, которые не являются делимыми 4. Результат - это, так как мы подаем его список чисел (вывод grep), каждая группа из 4 чисел будет распечатана на той же строке начиная с \n был преобразован в a ..
  • perl -pe 's/^/$.. /' : Просто добавьте текущий номер строки к началу каждой строки.

Steeldriver предложил очень хорошую альтернативу:

grep -oP '@\K\d+' file | xargs -n4 printf '%d.%d.%d.%d\n' | cat -n

Который заставил меня думать об этом:

printf '%d.%d.%d.%d\n' $(grep -oP '@\K\d+' file ) | cat -n

Если бы Вам нравится, можно сделать все это в Perl и избежать каналов, но я использовал бы метод выше. Так или иначе, всегда предполагая, что Ваши числа окружаются @, это будет также работать:

perl -ne 'push @f,(/@(\d+)@/g); 
          END{
            $k=1;
            for($i=0;$i<=$#f;$i+=4){
                print "$k. " . join(".",@f[$i..($i+3)]) . "\n"; $k++}
            }' file

Можно вставить это непосредственно в терминал, просто измениться file для фактического имени файла. Вывод похож на это:

1. 192.168.10.16
2. 192.169.10.16
3. 192.128.10.16
4. 192.162.10.16

Объяснение

  • perl -ne : считайте входной файл линию за линией (-n) и примените сценарий, данный -e.

  • push @f,(/@(\d+)@/g); : Сохраните каждое число, окруженное @ как элемент @f массив.

  • END{} : сделайте это после того, как Вы закончите обрабатывать все строки
  • for($i=0;$i<=$#f;$i+=4){} : выполните итерации через массив. Начиная с дюйм/с имеют 4 набора чисел, мы читаем массив в переходах четыре.
  • join(".",@f[$i..($i+3)]) : Это соединяет 4 элемента массива с . для печати.
  • $k должен только распечатать числа перед дюйм/с.

6
ответ дан 10 November 2019 в 18:04

Может быть необычный способ сделать это с терминалом, но я не знаю как. Вот то, как я сделал бы это с помощью Python

Скопируйте этот код в новый файл, назовите его whatEverYouWant.py и измените строку, которая говорит 'input.txt', чтобы быть 'yourFileWithIps.txt'

import re

validIpAddressRegex = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$";

ips = []
with open('input.txt','r') as f:
    output = f.read()
    ips = re.findall(r'[0-9]+(?:\.[0-9]+){3}', output)

for x in range(1, len(ips) + 1):
    print str(x) + '.' + ips[x-1]

затем от терминала перешли туда, где Вы сохранили whatEverYouWant.py и тип

python whatEverYouWant.py

и это должно произвести то, что Вы хотите.

Результаты моего собственного теста

cam@cam-P5E:~/Desktop$ python getips.py
1.192.168.0.1
2.255.255.255.0
3.10.0.0.1
4.192.192.192.192
0
ответ дан 10 November 2019 в 18:04

Использование GNU sed

Вы могли также использовать sed с этой целью. Принятие чисел в ipaddress является существующим промежутком @@ символы.

$ sed 's/.*@\(.*\)@.*@\(.*\)@.*@\(.*\)@.*@\(.*\)@.*/\1.\2.\3.\4/g' file
192.168.10.16
192.169.10.16
192.128.10.16
192.162.10.16

Ниже команды помещает число в порядок перед выбранными IP-адресами,

$ sed 's/.*@\(.*\)@.*@\(.*\)@.*@\(.*\)@.*@\(.*\)@.*/\1.\2.\3.\4/g' file | awk '{ print NR". "$0}' 

Пример:

$ echo 'So what the@192@ heck are you doing@168@ in my house @10@.you were not @16@ supposed to be here.' | sed 's/.*@\(.*\)@.*@\(.*\)@.*@\(.*\)@.*@\(.*\)@.*/\1.\2.\3.\4/g' | awk '{ print NR". "$0}'
1. 192.168.10.16

Объясните свой код немного?

sed 's/.*@\(.*\)@.*@\(.*\)@.*@\(.*\)@.*@\(.*\)@.*/\1.\2.\3.\4/g' file | awk '{ print NR". "$0}'
|                                                                   |   |                     |
|                                                                   |   |                     |
|<----------------------First part--------------------------------->|   |<-----Second part--->|   

OP упомянула, что IP-адреса скремблированы (распространение) на всем протяжении файла с каждой частью ipaddress, во включают @@ и каждая строка содержит четыре @...@ части. Таким образом, он хочет выбрать весь подарок чисел внутри @@ линию за линией и печать это в формате IP-адреса (xxx.xxx.xxx.xxx).

Первая часть

sed анализирует входной файл линию за линией.

Рассмотрите ниже regex в моем коде и также вышеупомянутом примере. Мы должны дать regex, который соответствует целой строке, и также это содержало бы выбирающие группы для выборки слов согласно нашим критериям, так, чтобы выбранная группа была снова использована через обратную ссылку.

Строка в качестве примера:

So what the@192@ heck are you doing@168@ in my house @10@.you were not @16@ supposed to be here.

Regex:

.*@\(.*\)@.*@\(.*\)@.*@\(.*\)@.*@\(.*\)@.*

.*

Это соответствует любому символу в 0 или больше раз кроме символа новой строки.

@\(.*\)@

В sed, ()(выбирающие группы), это круглые скобки используются для выборки группы символов или слов или чисел. По умолчанию sed использует основной regex, таким образом, мы должны выйти из круглой скобки inorder для создания выборки для работы. Но если Вы используете sed с -r(extended-regex) флаг, Вам не нужен выход.

В нашем случае это \(.*\) , оставляют обеих открытых и закрывающих квадратных скобок. На sed чтение целой строки это останавливает соответствие и начинает выбирать все символы или числа или что-либо после @ символ и остановки, выбирающие, пока это не находит следующее @ символ. Затем это хранит выбранную группу в специальном названном буфере (пространство шаблона). так, чтобы выбранные символы использовались бы далее. Теперь sed выбирает числа между первым @@ символы (я, e.192).

.*

После ловли первой группы, sed начинает анализировать следующие символы и соответствует чему-либо 0 или больше раз.

@\(.*\)@

Выберите числа между вторым @@ символы. (я, e 168)

.*

Соответствия любой и затем это идет дальше.

@\(.*\)@

Выберите числа между третьим @@ часть. (т.е. 10)

.*

Соответствия любой и затем это идет дальше.

@\(.*\)@

Выберите числа между четвертым @@ часть. (т.е. 16)

.*

Там может, или может - не быть символами, существующими после четвертого @@ символы. Таким образом, мы должны дать это .* для соответствия всем символам после четвертого @@ часть.

Так sed выбирает точные числа, мы хотим и сохранили его в буфере.

Формат по умолчанию (синтаксис) sed,

sed 's/regex/replacement/g' file

код:

sed 's/.*@\(.*\)@.*@\(.*\)@.*@\(.*\)@.*@\(.*\)@.*/\1.\2.\3.\4/g' file

таким образом, sed ищет соответствие этого regex. После того как это находит соответствие, это будет заменено сменной деталью. И g глобальный флаг помогает заменить все случаи строки regex со сменной деталью. (g-global).

В нашем случае regex будет соответствовать первой строке, и целая строка была бы заменена нашими выбранными группами 1,2,3,4. Затем sed делает эту операцию на всех строках, которая соответствует нашему regex. В сменной детали выбранными группами предшествуют \. И следовательно это назвало ссылку спины. Если нам не удается разделить группы .(точки),

\1\2\3\4

вывод был бы,

1921681016

Таким образом, мы должны разделить группы с .(точки). Так, чтобы это было бы появляться в формате IP-адреса.

\1.\2.\3.\4

Теперь вывод был бы,

192.168.10.16

Вторая часть

awk '{ print NR". "$0}'

Теперь вывод sed для первой строки был бы 192.168.10.16. Этот вывод чествовался, как введено к второму awk команда.

  • Awk NR(Количество Записей), переменная хранит строку или рекордное число. Обратите внимание что, наконец значение NR был бы последний номер строки. Как sed , awk анализирует входной файл линию за линией. Так NR значение 1-й строки было бы 1, и вторая строка будет 2 и так далее.

  • В функции печати awk был бы распечатан символ, как это, если это было помещено в двойных кавычках. Таким образом, это печатает . после номера строки (я, e текущий НОМЕР).

  • $0 печатает целую строку как есть.

Таким образом, вывод целой команды был бы,

$ sed 's/.*@\(.*\)@.*@\(.*\)@.*@\(.*\)@.*@\(.*\)@.*/\1.\2.\3.\4/g' file | awk '{ print NR". "$0}'
192.168.10.16
192.169.10.16
192.128.10.16
192.162.10.16

Можно также использовать эту команду,

sed 's/.*@\([0-9]\+\)@.*@\([0-9]\+\)@.*@\([0-9]\+\)@.*@\([0-9]\+\)@.*/\1.\2.\3.\4/g' file

Пример:

$ echo 'So what the@192@ heck are you doing@168@ in my house @10@.you were not @16@ supposed to be here.' | sed 's/.*@\([0-9]\+\)@.*@\([0-9]\+\)@.*@\([0-9]\+\)@.*@\([0-9]\+\)@.*/\1.\2.\3.\4/g'
192.168.10.16
3
ответ дан 3 December 2019 в 06:21

Другие вопросы по тегам:

Похожие вопросы: