使用Python脚本导出IP地址

时间:2016-03-07 15:24:30

标签: python regex

我正在尝试创建一个脚本,该脚本将提取出现超过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并且还习惯了。

3 个答案:

答案 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))