我有一个包含用户ID和IP地址的大型日志文件。我正在尝试确定查看特定IP登录的用户ID的最佳方式。
最初我认为我可以通过命令行上的cut,sort和uniq来做到这一点,但我没有得到我想要的输出。 Python或bash解决方案将是理想的选择。
以下是该文件的示例:
eric 1.1.1.1
eric 1.1.1.1
brian 1.1.1.1
jeff 1.1.1.1
eric 2.2.2.2
bob 3.3.3.3
jeff 3.3.3.3
eric 1.1.1.1
eric 1.1.1.1
eric 4.4.4.4
peter 4.4.4.4
我希望输出显示此类信息:
eric - 1.1.1.1, 2.2.2.2, 4.4.4.4
brian - 1.1.1.1
jeff - 1.1.1.1, 3.3.3.3
bob - 3.3.3.3
peter - 4.4.4.4
以及:
1.1.1.1 - eric, brian, jeff
2.2.2.2 - eric
3.3.3.3 - bob, jeff
4.4.4.4 - peter
随着它的成熟,我将不得不为排除IP创建一个变量,我们可以说1.1.1.1是一个NAT并且受信任,所以我们可以忽略它,因为有多个用户来自它。
欣赏正确的方向。
答案 0 :(得分:4)
考虑以下脚本,用input-process-output样式编写。
一些注意事项:
fileinput
模块允许您在命令行上指定单个输入文件名,多个文件名或根本没有文件名(在这种情况下它将使用stdin)。
defaultdict
可让您方便地收集数据集。
', '
join生成所需的逗号分隔输出行。
使用生成器表达式(line.split() for line ...)
而不是列表推导[line.split() for line ...]
可以节省内存(你说这些是大文件)。如果您使用了列表推导,则可以将所有数据存储在内存中两次。
随着代码的成熟,您可以切换到argparse
来控制您添加的新功能。
import fileinput
import collections
# Input the data
raw_data = (line.split() for line in fileinput.input())
# Process the data
name2ip = collections.defaultdict(set)
ip2name = collections.defaultdict(set)
for name, ip in raw_data:
name2ip[name].add(ip)
ip2name[ip].add(name)
# Output the data
for name, ips in name2ip.items():
print '%s - %s'%(name, ', '.join(ips))
for ip, names in ip2name.items():
print '%s - %s'%(ip, ', '.join(names))