我有一份文件列表,其中列出了我们工作系统中某个地方丢失的文件。我还有一个文件夹,里面有 41 个日志文件,总计 46 MB,希望这些文件包含与丢失文件相关的日志条目。我该如何查找这些日志文件中列表中的任何值?
该列表的结构为每行一个文件,没有文件扩展名。日志似乎有一个结构,但我还不完全熟悉该结构。它确实包含文件名和路径以及对它执行的操作。
我知道我可以获取cat *
所有日志文件并将其传输到grep
。当找到名称时,我可能会使用-A
并-B
从日志文件中获取一些上下文。我在 Windows 上使用 GnuWin32,因此我可以将其与 Powershell 结合使用,但我认为这样做需要一个文件名 grep 所有 46 MB,当我移动到下一个文件名时,我会重新开始。我的列表中有 1830 个文件,所以如果我必须从每个文件开始,我最终会读取 46 MB 很多次,以至于我将处理 GB 的重复数据。这样做似乎效率低下。
我想我可以构建一个包含 1830 个文件的大型正则表达式,然后针对日志运行一次,但这可行吗?正则表达式将接近 30KB(1830 个文件 * 文件名平均长度约为 16 个字符 = 29280 字节,更不用说另外 1830 字节的管道符号了)。
编辑:当我在日志文件夹中并且列表位于一个文件夹后面时,我正在执行的操作如下:
$logs = gc *
$notfound = gc ../notfound.txt
$logs | % { $i = 0; while ($i -lt $notfound.Count) { if ($_ -contains $notfound[$i]) { echo $_ }; $i++; } } | out-file C:\discovered.txt
它完全是 powershell。我愿意使用任何工具来加快速度,因为现在所有日志文件加起来有 550991 行,文件名有 1830 个,所以这种方法1,008,313,530 次比较。一切都在内存中,所以至少没有磁盘 I/O 拖慢我的速度。while
如果结果if
为真,我可能能够摆脱这种情况,但我仍然会进行如此多的比较,我不确定优化是否真的会有什么好处。它已经运行了半个小时。如果我能在周末回家之前完成,我可以从第 1 行重写我的方法。
答案1
通过正则表达式从日志中提取文件名并查看每个文件名是否都在列表中会更有效。它可能看起来像这样:
$notfound = gc ../notfound.txt
gc * |
select-string -AllMatches '\\(?<filename>[^\\]+)\.txt' |
select -ExpandProperty Matches |
% { $_.Groups['filename'].Value } |
? { $notfound -contains $_ } |
out-file C:\discovered.txt
我正在搜索类似于“\something.txt”的文件。您必须更改它。
如果它仍然太慢并且你的未找到列表非常大,那么将其加载到 .Net HashSet 中可能会更有效率,但除非需要,否则我不会这样做。