2016-03-07 67 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))