lua日志文件处理代码
作者:BrightSoul
时间:2026-06-29
来源:互联网
浏览:0
一个基于Lua的日志搜索工具,允许用户自定义搜索后的处理函数,实现字段提取、条件过滤与汇总统计,省去手动复制到Excel的环节。虽搜索速度较慢,但日常使用已显著提升效率。
在日常开发中,日志搜索几乎是每个技术人都会碰到的家常便饭。市面上那些文件夹搜索工具,单行检索还行,可一旦涉及到对搜索结果做自定义处理——比如提取关键字段、按条件过滤、再汇总统计——就有点力不从心了。常见做法是先搜出来,粘到 Excel 里再折腾一番,既费时又容易出错。

于是,直接用 Lua 搓了一个小工具,核心思路就是让使用者自定义搜索后的处理函数,省掉中间手动搬运数据的环节。下面直接看代码。
-- search_log.lua
tbResult = {};
tbCmdResult = {};
local szTmpFolderPath = os.getenv("temp");
if not szTmpFolderPath then
os.execute("md c:\temp")
szTmpFolderPath = "c:\temp";
end
local tbSpecialWorld =
{
["("] = "%(", [")"] = "%)", ["."] = "%.", ["%"] = "%%",
["+"] = "%+", ["-"] = "%-", ["*"] = "%*", ["?"] = "%?",
["["] = "%[", ["]"] = "%]", ["^"] = "%^", ["$"] = "%$",
};
function FormatCmd(szCmd)
return string.gsub(szCmd, ".", function(s) return tbSpecialWorld[s] or s; end)
end
function FormatPath(szPath)
string.gsub(szPath, "[\/]$", "");
return string.gsub(szPath, "/", "\");
end
function CheckFile(szFilePath)
local file = io.open(szFilePath, "rb");
if not file then
return;
end
file:close();
return true;
end
function OpenFile(szFilePath)
if not CheckFile(szFilePath) then
return;
end
local tbFile = {};
for line in io.lines(szFilePath) do
table.insert(tbFile, line);
end
return tbFile;
end
function SearchFile(szFilePath, szCmd, fnCmd2Line, fnFileName)
local tbFile = OpenFile(szFilePath);
if not tbFile then
return;
end
tbResult[szFilePath] = tbResult[szFilePath] or {};
local szCmdResult = "";
for nLine, szLine in ipairs(tbFile) do
if string.match(szLine, szCmd) then
szCmdResult = fnCmd2Line(szLine);
if szCmdResult and szCmdResult ~= "" then
table.insert(tbCmdResult, szCmdResult);
end
table.insert(tbResult[szFilePath], nLine .. ":" .. szLine);
end
end
return 1;
end
function Cmd2Line(szLine)
return;
end
function CheckName(szFileName)
return true;
end
function SearchDir(szFolderPath, szCmd, fnCmd2Line, fnCheckName, nIdx)
if not szCmd or szCmd == "" then
return;
end
local fnCmd2Line = fnCmd2Line or Cmd2Line;
local fnCheckName = fnCheckName or CheckName;
local nIdx = nIdx or 0;
local szTmpFileName = szTmpFolderPath .. "\SearchDirTemp" .. nIdx .. ".tmp";
os.execute("dir /b ".. szFolderPath .." >" .. szTmpFileName);
local tbFile = OpenFile(szTmpFileName);
if not tbFile or #tbFile == 0 then
return;
end
local szPath = "";
for _, szFileName in ipairs(tbFile) do
szPath = szFolderPath .. "\" .. szFileName;
if not CheckFile(szPath) then
SearchDir(szPath, szCmd, fnCmd2Line, nIdx + 1);
else
if CheckName(szFileName) then
SearchFile(szPath, szCmd, fnCmd2Line);
end
end
end
end
function Write2File(szInfo, szFilePath)
local file = io.open(szFilePath, "w");
if not file then
print(szInfo);
print("Write2File ERR ?? not file " .. szFilePath);
return;
end
file:write(szInfo);
file:close();
end
function DoSearchDir(szFolderPath, szCmd, tbParam)
if not szFolderPath or szFolderPath == "" or not szCmd or szCmd == "" then
return;
end
tbParam = tbParam or {};
szFolderPath = FormatPath(szFolderPath);
if tbParam.bIsMatch then
szCmd = FormatCmd(szCmd);
end
local nTime = os.time();
SearchDir(szFolderPath, szCmd, tbParam.fnCmd2Line or Cmd2Line, tbParam.fnCheckName or CheckName, 0);
nTime = os.time() - nTime;
print("搜索用时:" .. nTime);
local szResultPath = tbParam.szResultPath or (szTmpFolderPath .. "\result.tab.tmp");
local szResult = "";
for szFilePath, tbInfo in pairs(tbResult) do
szResult = szResult .. szFilePath .. "n";
for _, szLine in pairs(tbInfo) do
szResult = szResult .. szLine .. "n";
end
end
Write2File(szResult, szResultPath);
local szCmdResult = "";
for _, szLine in pairs(tbCmdResult) do
szCmdResult = szCmdResult .. szLine .. "n";
end
Write2File(szCmdResult, tbParam.szCmdResultPath or (szTmpFolderPath .. "\cmd_result.tab.tmp"));
end
--tbParam =
--{
-- bIsMatch = false; -- 是否使用正则方式搜索
-- fnCmd2Line = function () end; -- 自定义搜索行内容处理函数
-- fnCheckName = function () end; -- 文件名限定函数
-- szResultPath = "e:\result.tab"; -- 文件搜索内容输出路径
-- szCmdResultPath = "e:\cmd_result.tab"; -- 自定义处理函数返回内容储存路径
--}
使用起来也很直观,下面的示例展示了如何从日志中提取玩家 ID 和最大次数,并且看起来是支持网络路径的:
dofile("e:\search_log.lua");
tbTmpInfo = {};
function CheckInfo(szLine)
local szPlayerName, nPlayerId, nCount = string.match(szLine, "^.*szType = finalt[^t]+t%d+t([^t]+)t(%d+)t(%d+).*$");
nPlayerId = tonumber(nPlayerId);
nCount = tonumber(nCount);
if nCount > tbTmpInfo[nPlayerId] then
tbTmpInfo[nPlayerId] = nCount;
return "" .. nPlayerId .. "t" .. nCount;
end
return;
end
tbParam =
{
bIsMatch = false;
fnCmd2Line = CheckInfo;
fnCheckName = function () return true; end;
szResultPath = "e:\result.tab";
szCmdResultPath = "e:\cmd_result.tab";
}
DoSearchDir("d:\logs", "szType = final", tbParam);
for _, szInfo in pairs(tbTmpInfo) do
print(szInfo);
end
目前还称不上完美——搜索速度偏慢,尤其在文件量大的时候感受比较明显。后续有时间再针对遍历和匹配效率做优化,不过眼下这个版本应付日常已经比来回倒腾 Excel 方便太多了。
作者最新文章
索尼 Xperia 1 VIII / VII / VI 等手机获 Android 17 更新,新增桌面模式等功能
2026-09-08 16:44
加拿大留学监护声明书(IMM 5646)双页签署与公证核对指南
2026-09-03 15:02
在线PDF转图片教程:一键生成高清图片包
2026-09-03 12:04
Creo零基础入门:新建零件与第一次拉伸建模完整指南
2026-09-03 06:02
扫描件PDF转Word的在线操作步骤与编辑可行性判断
2026-09-02 18:39
上一篇:
lua 基础教程
热门文章
更多
精品专题
更多
Mac软件
更多
WINDOWS
更多
Windows 10
Windows
Windows 10 是一款微软推出的经典操作系统,拥有硬件兼容性与多任务处理能力。它更偏向把系统状态查看和常用调节动作放在一起,适合需要持续观察和微调设备状态的场景。
极度公式
Windows/macOS/Linux
极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。
















