механизм linux + find с нерегулярным выражением (команда find) или perl - PullRequest
2 голосов
/ 07 сентября 2010

привет, дорогие друзья и доброе утро

Следующий вопрос может быть сложным и критическим для моих систем

У меня есть 4 машины Linux с кластером

Моя цель - найти все виды IP-адресов (xxx.xxx.xxx.xxx) в каждом файле системы linux

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

как следующее

больше /etc/inet/file.example1

 182.23.2.4
 255.255.0.0
 10.10.1.1
 19.2.*.*
 127.0.0.1

больше /etc/dir/file1.example2

 1.1.1.1 TCP

Etc .................

Могу ли я получить креативное предложение, чтобы найти все IP-адреса и распечатать их

Lidia

Ответы [ 3 ]

2 голосов
/ 07 сентября 2010

Когда их попросят сопоставить IP-адрес, многие напишут

/\d+\.\d+\.\d+\.\d+/

, но это даст ложные срабатывания.В Джеффри Фридла "Освоение регулярных выражений" автор дает образец для сопоставления IP-адресов, который гораздо более осторожен.Приведенный ниже код заимствован у Фридла, чтобы вызвать не произвольный набор цифр, а в диапазоне от 0 до 255, требует, чтобы адрес начинался и заканчивался на границах слова (\b), и запрещал адрес 0.0.0.0.

Без аргументов приведенный ниже код по умолчанию соответствует текущему каталогу для начала его поиска.Для поиска по всем файлам укажите корневой каталог в качестве аргумента.Открывая каждый путь, который выводит find, мы затем ищем в каждой строке IP-адрес и печатаем все совпадения вместе с соответствующими путями.

Обратите внимание, как код использует local для прозрачного переключения между символом NUL и символом новой строки для разделителя записей $/.Это необходимо, потому что действие find -print0 разделяет имена файлов с помощью '\0', но '\n' является разделителем строки.С -T мы ищем только текстовые файлы.

#! /usr/bin/perl

use warnings;
no warnings 'exec';
use strict;

my $octet = qr/[01]?\d\d?|2[0-4]\d|25[0-5]/;

my $ip = qr/ \b
             (?!0+\.0+\.0+\.0+\b)
             $octet(?:\.$octet){3}
             \b
           /x;

@ARGV = (".") unless @ARGV;
open my $find, "-|", "find", @ARGV, "-type", "f", "-print0"
  or die "$0: failed to start find: $!\n";

$/ = "\0";
while (defined(my $path = <$find>)) {
  chomp $path;
  next unless -T $path;
  if (open my $fh, "<", $path) {
    local $/ = "\n";
    while (<$fh>) {
      print "$path: $_" if /$ip/;
    }
    close $fh;
  }
  else {
    warn "$0: open $path: $!\n";
  }
}
0 голосов
/ 08 сентября 2010

Для поиска в файлах я почти всегда использую ack .

Простой шаблон, который, как отмечает gbacon, приведет к ложным срабатываниям:

ack -uo '\b\d+\.\d+\.\d+\.\d+\b' /

Опция -u устанавливает неограниченное соответствие ack, ack обычно пропускает каталоги метаданных контроля версий, такие как .svn и резервные файлы. Опция -o выведет часть каждой совпадающей строки вместо всей совпадающей строки.

Та же идея, но с использованием лучшего шаблона gbacon:

ack -uo '\b(?!0+\.0+\.0+\.0+\b)(?:[01]?\d\d?|2[0-4]\d|25[0-5])(?:\.(?:[01]?\d\d?|2[0-4]\d|25[0-5])){3}\b' /

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

ack -uo --literal 123.34.5.23 /

0 голосов
/ 07 сентября 2010

В Linux (где grep поддерживает рекурсивный поиск) и при условии, что для каждой строки используется не более 1 IP-адреса, следующий код будет работать (--include & --exclude не обязательны, поиск начинается рекурсивно с $ PWD).

grep -r -P [--include=PATTERN --exclude=PATTERN]\
  '\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b' $PWD |\
  perl -ne 'print "$1\n" if /\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b/;'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...