linux +查找机制与不规则expression式(查找命令)或Perl

嗨亲爱的朋友,早上好

以下问题对于我的系统来说可能是复杂和关键的

我有4个Linux集群的机器

我的目标是在Linux系统的每个文件中find所有types的IP地址(xxx.xxx.xxx.xxx)

备注:需要扫描linux系统中的每个文件,并validation文件是否包含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 

等等……………..

我可以得到一些创造性的build议,search所有的IP地址,并打印出来

利迪娅

当被要求匹配一个IP地址时,许多人会写

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

但这会给误报。 在杰弗里·弗里德尔的“ 掌握正则表达式”中 ,作者给出了一个更加小心的匹配IP地址的模式。 下面的代码借用了Friedl强制的不是任意的数字运行,而是从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"; } } 

在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/;' 

为了搜索文件,我几乎总是使用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 /