2016-05-21 3 views
0

я получил таблицу Mnesia, которая состоит из следующих форматов:Erlang: Запись Mnesia таблицы .csv одной записи в каждой строке

-record(state, {key, tuple, state, timestamp, fin_from}).

записей выглядеть следующим образом (читай с ets:tab2list(Tab)):

[{state,{80,43252,tcp,tcp_syn_received,{192,168,101,5},{192,168,101,89}}, 
     {80,43252,tcp,{192,168,101,5},{192,168,101,89}}, 
     tcp_syn_received,1463850419221,undefined}, 
{state,{80,41570,tcp,tcp_syn_received,{192,168,101,5},{192,168,101,89}}, 
     {80,41570,tcp,{192,168,101,5},{192,168,101,89}}, 
     tcp_syn_received,1463850403214,undefined}, 
...] 

Я хотел бы записать эти данные в файл .csv с одной записью в строке - привилегированную в следующем формате:

state,80,43252,tcp,tcp_syn_received,192.168.101.5,192.168.101.89,80,43252,tcp,192.168.101.5,192.168.101.89,tcp_syn_received,1463850419221,undefined 
state,80,41570,tcp,tcp_syn_received,192.168.101.5,192.168.101.89,80,41570,tcp,192.168.101.5,192.168.101.89,tcp_syn_received,1463850419221,undefined 

Должно быть разлом строки после undefined. Я попытался с помощью следующего кода (при Content = ets:tab2list(states)):

do_logging_async(File, Format, Content, Append)-> 
F = fun() -> 
    file:write_file(File, io_lib:fwrite(Format, [Content]), [Append]) 
end, 
spawn(F). 

Однако, я не могу получить что-нибудь подобное моему выходу. Данные должны впоследствии оцениваться с R.

UPDATE: Ключ в том, чтобы прочитать строку таблицы по строкам и разобрать его с ~w, но не ~p. Я в конечном итоге со следующим раствором (который производит несколько иного вывод, однако, есть меньше избыточные данные):

do_state_logging(File, EtsAsList) -> 
% write header (columnnames) 
file:write_file(File, io_lib:fwrite("~w,~w,~w,~w,~w,~w,~w,~w~n", [record,dstPort,srcPort,proto,dstIP,srcIP,state,timestamp]),[append]), 
case EtsAsList of 
    [] -> 
     ok; 
    _ -> 
     F = fun({Record,_Key, 
      [P1, P2, Proto, {D_Ip_1,D_Ip_2,D_Ip_3,D_Ip_4}, {S_Ip_1,S_Ip_2,S_Ip_3,S_Ip_4}], 
      State, Timestamp, _}) -> 
      file:write_file(File, io_lib:fwrite("~w,", [Record]),[append]), 
      file:write_file(File, io_lib:fwrite("~w,~w,~w,", [P1,P2,Proto]),[append]), 
      file:write_file(File, io_lib:fwrite("~w.~w.~w.~w,", [D_Ip_1,D_Ip_2,D_Ip_3,D_Ip_4]), [append]), 
      file:write_file(File, io_lib:fwrite("~w.~w.~w.~w,", [S_Ip_1,S_Ip_2,S_Ip_3,S_Ip_4]), [append]), 
      file:write_file(File, io_lib:fwrite("~w,", [State]),[append]), 
      file:write_file(File, io_lib:fwrite("~w", [Timestamp]),[append]), 
      file:write_file(File, ["\n"],[append]) 
     end, 
     lists:foreach(F, EtsAsList) 
    end, 
    io:format("Finished logging of statetable to file: ~p~n" , [File]). 

Благодаря ответу, который подтолкнул меня к этой идее.

+0

Возможно ли сохранить ваши значения ets в виде списков, а не кортежей? т.е. [80,43252, tcp, tcp_syn_received, [192,168,101,5], [192,168,101,89]], [80,43252, tcp, [192,168,101,5], [192,168,101,89]], tcp_syn_received, 1463850419221, не определено] '. Потому что тогда будет проще сгладить и записать каждую пластинку в виде строки. –

+0

Да, я мог бы это сделать. Но как мне разобрать отдельные строки (и списки)? – muehsi

ответ

1

Предполагая, что вы меняете свои значения, записывайте значения в списки, а не кортежи, вы можете использовать этот код для записи таблицы ETS в файл.

do_logging_async(File, EtsAsList) -> 
    F = fun({Key, Value}) -> 
     file:write_file(File, [atom_to_list(Key) ++ ","],[append]), 
     write_value(File,lists:flatten(Value)), 
     file:write_file(File, ["\n"],[append]) 
    end, 
    lists:foreach(F,EtsAsList). 


write_value(_File, []) -> ok; 
write_value(File, [H|T]) -> 
    case is_integer(H) of 
     true -> file:write_file(File, [integer_to_list(H)],[append]); 
     false -> file:write_file(File, [atom_to_list(H)],[append]) 
    end, 
    case T=:=[] of 
     true -> ok; 
     false -> file:write_file(File, [","],[append]) 
    end, 
    write_value(File,T). 

do_logging_async/2 принимает каждую {Key, Value} пару. Сначала он записывает Key в файл, а затем он запускает write_value/2 на Value, в конце каждой пары он пишет \n.

write_value/2 принимает список значений сглаживания (при условии, что это список сглаживания, который содержит только целые числа и атомы) и записывает его в файл.

+0

Я адаптировал его в своем формате: 'do_logging_async (File, EtsAsList) -> списки: foreach (fun ({state, Key, Key_no_state, State, Timestamp, _Val4}) -> % io: format (" Написание во время этого Итерация: {Key, Key_no_state, State, Timestamp, _Val4} ~ p ~ n ", [{Key, Key_no_state, State, Timestamp, _Val4}]), file: write_file (Файл, [Key ++", "], [добавить]), ... write_value (файл списка: выравниваться ([Отметка])), файл: write_file (файл, [ "\ п"], [добавить]) конец, EtsAsList) .' Однако записываются только временные метки. файл: write_file() return {ошибка, badargs} .. dunno, как идти дальше. – muehsi

+0

Вам нужно изменить свои пары '{Key, Value}', чтобы быть '{state, [Key, Key_no_state, State, Timestamp, Fin_from]} ', а затем просто используйте мой код как есть, и он должен работать. –