我正在尝试创建一个脚本,该脚本将提取出现超过30次(相同地址)的IP地址(来自文本文档)。一旦找到,我正在尝试将这些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 :(得分: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))
答案 1 :(得分:0)
(Failed).*?(password).*?\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}
它只包含您要查找的行,而不包括其中包含ip-address的所有行。
但我远离正则表达专家,可能并不完美。
你可以here来摆弄你的正则表达式。
答案 2 :(得分: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))