Подтвердить что ты не робот

Как вы извлекаете IP-адреса из файлов с помощью регулярного выражения в оболочке linux?

Как извлечь текстовую часть с помощью регулярных выражений в оболочке Linux? Допустим, у меня есть файл, где в каждой строке указан IP-адрес, но в другой позиции. Какой самый простой способ извлечь эти IP-адреса, используя обычные инструменты командной строки Unix?

4b9b3361

Ответ 1

Вы можете использовать grep, чтобы вытащить их.

grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' file.txt

Ответ 2

Большинство примеров здесь будут соответствовать 999.999.999.999, которые не являются технически корректным IP-адресом.

Следующее будет соответствовать только действительным IP-адресам (включая сетевые и широковещательные адреса).

grep -E -o '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' file.txt

Опустите -o, если вы хотите увидеть всю строку, которая соответствует.

Ответ 3

Обычно я начинаю с grep, чтобы получить регулярное выражение справа.

# [multiple failed attempts here]
grep    '[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*'                 file  # good?
grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' file  # good enough

Затем я попытаюсь преобразовать его в sed, чтобы отфильтровать остальную часть строки. (После прочтения этой темы мы с вами больше не будем этого делать: вместо этого мы будем использовать grep -o)

sed -ne 's/.*\([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\).*/\1/p  # FAIL

Это, когда меня обычно раздражает sed за то, что вы не используете те же регулярные выражения, что и другие. Поэтому я перехожу к perl.

$ perl -nle '/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/ and print $&'

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

$ perl -MRegexp::Common=net -nE '/$RE{net}{IPV4}/ and say $&' file(s)

Ответ 4

Это работает отлично для меня в журналах доступа.

cat access_log | egrep -o '([0-9]{1,3}\.){3}[0-9]{1,3}'

Позвольте разбить его по частям.

  • [0-9]{1,3} означает от одного до трех вхождений диапазона, упомянутого в []. В этом случае это 0-9. поэтому он соответствует шаблонам, например, 10 или 183.

  • Далее следует '.'. Нам нужно будет избежать этого как. является метасимволом и имеет особое значение для оболочки.

Итак, теперь мы находимся на шаблонах типа '123.' '12 ". и др.

  • Этот шаблон повторяется три раза (с символом '.'). Поэтому мы заключим его в скобки. ([0-9]{1,3}\.){3}

  • И, наконец, образец повторяется, но на этот раз без ".". Вот почему мы сохранили его отдельно на третьем этапе. [0-9]{1,3}

Если ips находятся в начале каждой строки, как в моем случае, используйте:

egrep -o '^([0-9]{1,3}\.){3}[0-9]{1,3}'

где '^' - это якорь, который сообщает, чтобы искать в начале строки.

Ответ 5

Я написал немного script, чтобы лучше видеть мои файлы журналов, это ничего особенного, но может помочь многим людям, которые обучение perl. Он выполняет поиск DNS по IP-адресам после их извлечения.

Ответ 6

Я написал информативную статью в блоге на эту тему: Как извлечь IPv4 и IPv6 IP-адреса из обычного текста с помощью Regex.

В статье приведено подробное руководство по наиболее распространенным различным шаблонам для IP-адресов, которые часто требуется извлекать и изолировать от простого текста с помощью регулярных выражений.
Это руководство основано на инструменте исходного кода CodVerter IP Extractor для обработки извлечения и обнаружения IP-адресов при необходимости.

Если вы хотите проверить и захватить IPv4-адрес, этот шаблон может сделать эту работу:

\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)[.]){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b

или для проверки и захвата IPv4-адреса с префиксом ("косая черта"):

\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)[.]){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?/[0-9]{1,2})\b

или для захвата маски подсети или маски:

(255|254|252|248|240|224|192|128|0)[.](255|254|252|248|240|224|192|128|0)[.](255|254|252|248|240|224|192|128|0)[.](255|254|252|248|240|224|192|128|0)

или отфильтровать маску подсети, адрес, которые вы делаете это с регулярным выражением отрицательного предпросмотром:

\b((?!(255|254|252|248|240|224|192|128|0)[.](255|254|252|248|240|224|192|128|0)[.](255|254|252|248|240|224|192|128|0)[.](255|254|252|248|240|224|192|128|0)))(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)[.]){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b

Для проверки IPv6 вы можете перейти по ссылке на статью, которую я добавил вверху этого ответа.
Вот пример для захвата всех распространенных шаблонов (взят из примера справки CodVerter IP Extractor):

enter image description here

Если вы хотите, вы можете проверить регулярное выражение IPv4 здесь.

Ответ 7

Вы можете использовать некоторый помощник оболочки, который я сделал: https://github.com/philpraxis/ipextract

включили их здесь для удобства:

#!/bin/sh
ipextract () 
{ 
egrep --only-matching -E  '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' 
}

ipextractnet ()
{ 
egrep --only-matching -E  '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/[[:digit:]]+' 
}

ipextracttcp ()
{ 
egrep --only-matching -E  '[[:digit:]]+/tcp' 
}

ipextractudp ()
{ 
egrep --only-matching -E  '[[:digit:]]+/udp' 
}

ipextractsctp ()
{ 
egrep --only-matching -E  '[[:digit:]]+/sctp' 
}

ipextractfqdn ()
{ 
egrep --only-matching -E  '[a-zA-Z0-9]+[a-zA-Z0-9\-\.]*\.[a-zA-Z]{2,}' 
}

Загрузите его/отправьте его (если он хранится в файле ipextract) из оболочки:

$. ipextract

Используйте их:

$ ipextract < /etc/hosts
127.0.0.1
255.255.255.255
$

Для примера реального использования:

ipextractfqdn < /var/log/snort/alert | sort -u
dmesg | ipextractudp

Ответ 8

grep -E -o "([0-9] {1,3} [.]) {3} [0-9] {1,3}"

Ответ 9

Вы можете использовать sed. Но если вы знаете perl, это может быть проще и более полезно знать в долгосрочной перспективе:

perl -n '/(\d+\.\d+\.\d+\.\d+)/ && print "$1\n"' < file

Ответ 10

Для тех, кто хочет получить готовое решение для получения IP-адресов из журнала apache и перечисления случаев, когда IP-адрес посещал веб-сайт, используйте эту строку:

grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' error.log | sort | uniq -c | sort -nr > occurences.txt

Хороший способ запретить хакеров. Далее вы можете:

  1. Удалить строки менее чем за 20 посещений
  2. Используя регулярное выражение, вырежьте до одного пробела, так что у вас будут только IP-адреса
  3. Используя regexp, вырежьте 1-3 последние цифры IP-адресов, чтобы у вас были только сетевые адреса
  4. Добавьте deny from и пробел в начале каждой строки
  5. Поместите файл результатов как .htaccess

Ответ 11

Я бы предложил perl. (\ d +.\d +.\d +.\d +), вероятно, должен сделать трюк.

EDIT: чтобы сделать его более похожим на полную программу, вы можете сделать что-то вроде следующего (не тестировалось):

#!/usr/bin/perl -w
use strict;

while (<>) {
    if (/(\d+\.\d+\.\d+\.\d+)/) {
        print "$1\n";
    }
}

Это обрабатывает один IP-адрес. Если у вас более одного IP-адреса в строке, вам нужно использовать опцию /g. man perlretut дает вам более подробное руководство по регулярным выражениям.

Ответ 12

Вы также можете использовать awk. Что-то вроде...

awk '{i = 1; if (NF > 0) do {if ($ я ~/regexp/) print $i; я ++;} while (i <= NF);} 'file

- может потребоваться очистка. просто быстрый и грязный ответ, чтобы показать в основном, как это сделать с awk

Ответ 13

Все предыдущие ответы имеют одну или несколько проблем. Принимаемый ответ позволяет номерам ip, например 999.999.999.999. В настоящее время второй наиболее рекомендуемый ответ требует префикса с 0, например 127.000.000.001 или 008.008.008.008 вместо 127.0.0.1 или 8.8.8.8. У Apama это почти правильно, но для этого выражения требуется, чтобы ipnumber был единственным в строке, не допускал никакого ведущего или конечного пробела и не мог выбрать ip из середины строки.

Я думаю, что правильное регулярное выражение можно найти на http://www.regextester.com/22

Итак, если вы хотите извлечь все ip-адреса из файла, используйте:

grep -Eo "(([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])" file.txt

Если вы не хотите, чтобы дубликаты использовали:

grep -Eo "(([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])" file.txt | sort | uniq

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

Ответ 14

Все здесь используют действительно длинные регулярные выражения, но на самом деле понимание регулярного выражения POSIX позволит вам использовать небольшую команду grep подобную этой, для печати IP-адресов.

grep -Eo "(([0-9]{1,3})\.){3}([0-9]{1,3})"

(Примечание) Это не игнорирует недействительные IP-адреса, но это очень просто.

Ответ 15

Я перепробовал все ответы, но у всех них была одна или несколько проблем, и я перечислил некоторые из них.

  1. Некоторые обнаружили 123.456.789.111 как действительный IP
  2. Некоторые не 127.0.00.1 действительным IP
  3. Некоторые не обнаруживают IP, которые начинаются с нуля, как 08.8.8.8

Поэтому здесь я публикую регулярное выражение, которое работает на всех вышеперечисленных условиях.

Примечание: я извлек более 2 миллионов IP без каких-либо проблем со следующим регулярным выражением.

(?:(?:1\d\d|2[0-5][0-5]|2[0-4]\d|0?[1-9]\d|0?0?\d)\.){3}(?:1\d\d|2[0-5][0-5]|2[0-4]\d|0?[1-9]\d|0?0?\d)

Ответ 16

Я хотел получить только IP-адреса, которые начинаются с "10", из любого файла в каталоге:

grep -o -nr "[10]\{2\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}" /var/www

Ответ 17

Если вам не указан конкретный файл, и вам нужно извлечь IP-адрес, нам нужно сделать это рекурсивно. grep command → Ищет текст или файл для соответствия данной строке и отображает согласованную строку.

grep -roE '[0-9] {1,3}. [0-9] {1,3}. [0-9] {1,3}. [0-9] {1,3} '| grep -oE '[0-9] {1,3}. [0-9] {1,3}. [0-9] {1,3}. [0-9] {1,3}'

-r → Мы можем выполнить поиск всего дерева каталогов, то есть текущего каталога и всех уровней подкаталогов. Он обозначает рекурсивный поиск.

-o → Печать только соответствующей строки

-E → Использовать расширенное регулярное выражение

Если бы мы не использовали вторую команду grep после этого канала, мы получили бы IP-адрес вместе с тем путем, в котором он присутствует.

Ответ 18

cat ip_address.txt | grep '^[0-9]\{1,3\}[.][0-9]\{1,3\}[.][0-9]\{1,3\}[.][0-9]\{1,3\}[,].*$\|^.*[,][0-9]\{1,3\}[.][0-9]\{1,3\}[.][0-9]\{1,3\}[.][0-9]\{1,3\}[,].*$\|^.*[,][0-9]\{1,3\}[.][0-9]\{1,3\}[.][0-9]\{1,3\}[.][0-9]\{1,3\}$'

Предположим, что файл разделен запятой и позиция ip-адреса в начале, в конце и где-то посередине

Первое регулярное выражение ищет точное соответствие ip-адреса в начале строки. Второе регулярное выражение после или ищет ip-адрес в середине. Мы сопоставляем его таким образом, что число, которое следует за ним, должно быть от 1 до 3 цифр .falsy ips, как 12345.12.34.1, может быть исключено в этом.

Третий regexp ищет ip-адрес в конце строки

Ответ 19

для centos6.3

ifconfig eth0 | grep 'inet addr' | awk '{print $2}' | awk 'BEGIN {FS=":"} {print $2}'