在Ruby中解析一个范围内的日志文件

时间:2015-01-26 12:27:34

标签: ruby parsing

我有一个很长的日志文件(+5000行)。以下是文件模式的示例:

  0:00 InitGame: \sv_floodProtect\1\sv_maxPing\0\sv_minPing\0\sv_maxRate\10000\sv_minRate\0\sv_hostname\Code Miner Server\g_gametype\0\sv_privateClients\2\sv_maxclients\16\sv_allowDownload\0\dmflags\0\fraglimit\20\timelimit\15\g_maxGameClients\0\capturelimit\8\version\ioq3 1.36 linux-x86_64 Apr 12 2009\protocol\68\mapname\q3dm17\gamename\baseq3\g_needpass\0
  0:25 ClientConnect: 2
  0:25 ClientUserinfoChanged: 2 n\Dono da Bola\t\0\model\sarge/krusade\hmodel\sarge/krusade\g_redteam\\g_blueteam\\c1\5\c2\5\hc\95\w\0\l\0\tt\0\tl\0
  0:27 ClientUserinfoChanged: 2 n\Mocinha\t\0\model\sarge\hmodel\sarge\g_redteam\\g_blueteam\\c1\4\c2\5\hc\95\w\0\l\0\tt\0\tl\0
  0:27 ClientBegin: 2
  0:29 Item: 2 weapon_rocketlauncher
  0:35 Item: 2 item_armor_shard
  0:35 Item: 2 item_armor_shard
  0:35 Item: 2 item_armor_shard
  0:35 Item: 2 item_armor_combat
  0:38 Item: 2 item_armor_shard
  0:38 Item: 2 item_armor_shard
  0:38 Item: 2 item_armor_shard
  0:55 Item: 2 item_health_large
  0:56 Item: 2 weapon_rocketlauncher
  0:57 Item: 2 ammo_rockets
  0:59 ClientConnect: 3
  0:59 ClientUserinfoChanged: 3 n\Isgalamido\t\0\model\xian/default\hmodel\xian/default\g_redteam\\g_blueteam\\c1\4\c2\5\hc\100\w\0\l\0\tt\0\tl\0
  1:01 ClientUserinfoChanged: 3 n\Isgalamido\t\0\model\uriel/zael\hmodel\uriel/zael\g_redteam\\g_blueteam\\c1\5\c2\5\hc\100\w\0\l\0\tt\0\tl\0
  1:01 ClientBegin: 3
  1:02 Item: 3 weapon_rocketlauncher
  1:04 Item: 2 item_armor_shard
  1:04 Item: 2 item_armor_shard
  1:04 Item: 2 item_armor_shard
  1:06 ClientConnect: 4
  1:06 ClientUserinfoChanged: 4 n\Zeh\t\0\model\sarge/default\hmodel\sarge/default\g_redteam\\g_blueteam\\c1\5\c2\5\hc\100\w\0\l\0\tt\0\tl\0
  1:08 Kill: 3 2 6: Isgalamido killed Mocinha by MOD_ROCKET
  1:08 ClientUserinfoChanged: 4 n\Zeh\t\0\model\sarge/default\hmodel\sarge/default\g_redteam\\g_blueteam\\c1\1\c2\5\hc\100\w\0\l\0\tt\0\tl\0
  1:08 ClientBegin: 4
  1:10 Item: 3 item_armor_shard
  1:10 Item: 3 item_armor_shard
  1:10 Item: 3 item_armor_shard
  1:10 Item: 3 item_armor_combat
  1:11 Item: 4 weapon_shotgun
  1:11 Item: 4 ammo_shells
  1:16 Item: 4 item_health_large
  1:18 Item: 4 weapon_rocketlauncher
  1:18 Item: 4 ammo_rockets
  1:26 Kill: 1022 4 22: <world> killed Zeh by MOD_TRIGGER_HURT
  1:26 ClientUserinfoChanged: 2 n\Dono da Bola\t\0\model\sarge\hmodel\sarge\g_redteam\\g_blueteam\\c1\4\c2\5\hc\95\w\0\l\0\tt\0\tl\0
  1:26 Item: 3 weapon_railgun
  1:29 Item: 2 weapon_rocketlauncher
  1:29 Item: 3 weapon_railgun
  1:32 Item: 3 weapon_railgun
  1:32 Kill: 1022 4 22: <world> killed Zeh by MOD_TRIGGER_HURT
  1:35 Item: 2 item_armor_shard
  1:35 Item: 2 item_armor_shard
  1:35 Item: 2 item_armor_shard
  1:35 Item: 3 weapon_railgun
  1:38 Item: 2 item_health_large
  1:38 Item: 3 weapon_railgun
  1:41 Kill: 1022 2 19: <world> killed Dono da Bola by MOD_FALLING
  1:41 Item: 3 weapon_railgun
  1:43 Item: 2 ammo_rockets
  1:44 Item: 2 weapon_rocketlauncher
  1:46 Item: 2 item_armor_shard
  1:47 Item: 2 item_armor_shard
  1:47 Item: 2 item_armor_shard
  1:47 ShutdownGame:

我需要做以下事情:

  • 每当有一个&#34; InitGame&#34;时,它应该开始一个新的哈希,比如game_1,game_2等等。
  • 当有一个&#34; Shutdowngame&#34;
  • 时,游戏结束
  • 在两者之间,我想计算总游戏数量(每次有一个&#34;被杀死的#34;),玩家的名字(在ClientUserinfoChanged n \ name行中),并计算杀戮数量对于每个玩家,也就是当他们杀死某人时。

我的问题是如何做到这一点。我能够找到&#34; InitGame&#34;通过做File.readlines("games.log") {|line| line.include?("InitGame")},但我遇到问题的主要是在中间提取所有这些信息并将所有内容添加到哈希中。

非常感谢。

1 个答案:

答案 0 :(得分:1)

您可以使用match通过正则表达式轻松“拆分”一行。您可以使用rubular来调试Ruby正则表达式。

这是一个首发示例:

File.foreach(LOGFILE) do |line|
  # split the logfile
  entry = line.match(/^\s*(\d+:\d{2}) ([^:]+): (.+)?$/)
  # Now we have:
  # entry[1] => timestamp (x:xx)
  # entry[2] => action (DoSomething)
  # entry[3] => additional information (2 item_armor_shard)

  next if entry.nil?
  case entry[2]
  when 'InitGame'
    # initialize a new game
    games[current] = { users: {} }

  when 'ShutdownGame'
    # rotate to next game
    current += 1

  when 'ClientConnect'
    # initialize the data structure
    games[current][:users][entry[3]] = {}

  when 'ClientUserinfoChanged'
    # we can here further split our 'info' part
    user = entry[3].match(/^(\d+) n\\([^\\]+)/)
    # user[1] => the numerical ID (as a string)
    # user[2] => the user Name
    games[current][:users][user[1]] = user[2]

  when 'ClientBegin'
    # add yout own code here
    # .. and so on for other actions ...

  else
    puts "Action #{entry[2]} not implemented!"

  end
end