2010-09-07 39 views
2

嗨親愛的朋友,大家上午好機制的Linux +找到不規則表達(find命令)或Perl

下面的問題可能很複雜和關鍵我的系統

我有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 

等...... ...........

我可以得到一些創造性的建議,搜索所有IP地址並打印它們

利迪婭

+1

同樣,這是超級用戶的問題。 – Johnsyweb 2010-09-07 09:35:48

+0

@Johnsyweb [常問問題](http://stackoverflow.com/faq)表示SU適用於「一般計算機軟件或硬件故障排除」。這是一個編程問題,而不是故障排除問題。 – 2010-09-07 12:57:24

+0

我坐正確。雖然沒有說明問題的原因,但似乎是關於解決網絡或安全問題。既然你用perl程序解決了這個問題,那麼顯然它就是家庭。 – Johnsyweb 2010-09-07 22:14:08

回答

2

當記者問到匹配的IP地址,許多人會寫

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

,但是這會給誤報。在Jeffrey Friedl的Mastering Regular Expressions中,作者給出了一個更加小心的IP地址匹配模式。下面的代碼借用了Friedl強制的不是任意的數字運行,而是從0到255的範圍,要求地址開始和結束在字邊界(\b),並且不允許地址0.0.0.0。

沒有參數時,下面的代碼默認爲當前目錄作爲搜索開始。要搜索所有文件,請提供根目錄作爲參數。打開find輸出的每條路徑,然後我們搜索每條線路的IP地址並打印所有匹配以及它們各自的路徑。

請注意代碼如何使用local在記錄分隔符$/的NUL字符和換行符之間來回切換。這是必要的,因爲find-print0操作將文件名與分開,但'\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

非常酷和強大的Perl腳本,我需要在我的系統上做一些測試,所以我會再次發送給你我最後的想法THX – lidia 2010-09-07 14:09:16

+0

順便說一句,如果我只想搜索IP - 123.34.5.23 – lidia 2010-09-07 14:13:02

+0

,所以我需要設置:我的$ octet = qr/123.34.5.23 /; ? – lidia 2010-09-07 14:13:49

0

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

但我還需要掃描你的例子給我的所有文件只在一個文件上找到IP,並且我需要找到並掃描linux sys中的所有文件 – lidia 2010-09-07 07:57:35

+0

@lidia - 它遞歸地工作。如果用/替換$ PWD,它會在所有文件中找到所有IP地址,但這需要很長時間 – bobah 2010-09-07 08:01:24

+0

好吧,我得到所有IP地址,我需要獲取與IP地址相關的文件,如何更改您的語法爲了獲得IP和文件的完整路徑? – lidia 2010-09-07 08:13:28

0

對於文件搜索,我幾乎總是使用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 /