2016-03-07 125 views
1

我試圖創建一個腳本來提取出現超過30次(同一地址)的IP地址(來自文本文檔)。一旦發現我試圖將這些IP地址導出到單獨的文本文檔中。使用Python腳本導出IP地址

這是我到目前爲止有:

import re 

appears = 0 

myLog = open('auth.log', 'r') 

for line in myLog: 
    if re.match(("^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$"), line): 
     attempts +=1 

print 'The number of times this IP Address appears is', appears 

當我運行該腳本,我不是在日誌文件中找到的任何IP地址,有數百個在那裏,但沒有被發現。正則表達式或不同事物的組合存在問題嗎?

是否有機會我可以創建一個正則表達式搜索以下:

> Failed password for bin from 211.167.103.172 

很抱歉,如果這是一個有點模糊,新的Python,仍然習慣的事情。

回答

0

這裏有兩個問題。第一個是正則表達式開頭的插入符號(^)。這意味着「從字符串的開始處開始搜索這個模式」。如果你的日誌文件看起來像Failed password for xxx.xxx.xxx.xxx,那麼開始的文本會使正則表達式失效。另一個問題是.match函數。這將在字符串的開始處開始搜索,就好像前面有一個插入符號一樣。與.search替換此,你應該是好的:

if re.search(("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$"), line): 


另一件事: appears變量被設置 for循環之外,所以每次迭代一個線時間它會重置變量。我會爲每個IP聲明一個計數字典,並在您循環時遞增值:

import re 

ip_counts = {} 

myLog = open('auth.log', 'r') 

for line in myLog: 
    match = re.search(("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$"), line) 
    if match: 
     ip = match.group() 
     if ip not in ip_counts: 
      ip_counts[ip] = 1 
     else: 
      ip_counts[ip] += 1 

for ip in ip_counts: 
    count = ip_counts[ip] 
    if count > 30: 
     print('IP {} had {} attempts.'.format(ip, count)) 
+0

另一個問題是 –

+0

嘗試'如果match'條款下打印的東西縮進。如果你沒有看到任何輸出,那麼正則表達式有問題。 – Rob

+0

你可以用日誌的幾行做出要點嗎?如果需要,可以用零清除任何IP。 https://gist.github.com/ – Rob

0

汝拉是在正確的軌道上。您也可以在正則表達式升級到以下幾點:

(Failed).*?(password).*?\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} 

這將只包括你正在尋找的線條,而不是所有的行與它的IP地址。

但是我遠離正則表達式專家,可能並不完美。

你可以去here擺弄你的正則表達式。

0

下面是一個簡化版本的表情:

import re 
from collections import Counter 

e = re.compile(r'((\d{1,3}\.){3}\d{1,3})') 

with open('log.txt') as f: 
    ips = Counter([e.search(line).group() for line in f if e.search(line)]) 

thirty_plus = [ip for ip,count in ips.most_common() if count > 30] 

with open('results.txt', 'w') as f: 
    f.write('\n'.join(thirty_plus))