如何统计文件日志中的唯一用户?

时间:2012-06-16 08:06:55

标签: erlang

给定一个txt日志文件,格式为:

USER_A timestamp1 otherstuff
USER_B timestamp2 otherstuff
USER_C timestamp3 otherstuff
USER_A timestamp4 otherstuff
USER_A timestamp5 otherstuff
USER_C timestamp6 otherstuff
USER_B timestamp7 otherstuff

您如何计算erlang中不同唯一身份用户的数量?我正在考虑逐行读取文件并使用proplists模块。每个用户都是一个键,其值将是出现的次数。读完文件后,我打电话给:

length(proplists:get_keys(List)).

这是实现我的结果的正确方法吗?

3 个答案:

答案 0 :(得分:4)

我也会使用sets模块,因为它既快又且不包含重复项。

以下代码应该完成这项工作:

{ok,Bin} = file:read_file("test"),
List = binary_to_list(Bin),
Usernames = [hd(string:tokens(X," ")) || X <- string:tokens(List,[$\n])],
sets:size(sets:from_list(Usernames)).

编辑:我删除了单行,因为它没有添加任何值

答案 1 :(得分:3)

使用sets模块中的集合来存储用户名然后使用sets:size/1可能更合适。

答案 2 :(得分:1)

日志文件通常很大,因此请考虑在递归函数中一次使用一行:

% Count the number of distinct users in the file named Filename                        
count_users(Filename) ->
    {ok, File} = file:open(Filename, [read, raw, read_ahead]),
    Usernames = usernames(File, sets:new()),
    file:close(File),
    sets:size(Usernames).

% Add all users in File, from the current file pointer position and forward,
% to Set.
% Side-effects: File is read and the file pointer is moved to the end.          
usernames(File, Set) ->
    case file:read_line(File) of
        {ok, Line} ->
            Username = hd(string:tokens(Line, " ")),
            usernames(File, sets:add_element(Username, Set));
        eof ->
            Set
    end.

您只需将其称为:count_users("logfile")

请注意usernames/2必须tail recursive才能有效运作。否则它会消耗更多的内存。