基于多列计数

时间:2016-12-05 21:41:06

标签: python bash

我有一个包含用户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并且受信任,所以我们可以忽略它,因为有多个用户来自它。

欣赏正确的方向。

1 个答案:

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