powershell - 大型文本文件的 -match 操作的速度问题
问题描述
我有一个包含 36 个 .log 文件的数据基础,我需要对其进行预处理,以便将它们加载到 pandas 数据框中,以便在 python 框架中进行数据可视化。
要提供一个 .log 文件中的单行示例:
[16:24:42]: Downloaded 0 Z_SYSTEM_FM traces from DEH, clients (282) from 00:00:00,000 to 00:00:00,000
从这里的几个来源和帖子中,我发现以下代码是性能最好的代码:
foreach ($f in $files){
$date = $f.BaseName.Substring(22,8)
((Get-Content $f) -match "^.*\bDownloaded\b.*$") -replace "[[]", "" -replace "]:\s", " "
-replace "Downloaded " -replace "Traces from " -replace ",.*" -replace "$", " $date"
| add-content CleanedLogs.txt
}
变量$date
包含日期,相应的 .log 文件正在记录。
我无法更改输入文本数据。我尝试使用 -raw 读取 1,55GB,但在处理完所有操作后,我无法拆分生成的单个字符串。此外,我尝试使用更多的正则表达式,但总运行时间并没有减少。也许有一种方法可以使用 grep 进行此操作?
也许有人有一个巧妙的调整来加速这个操作。目前,此操作需要将近 20 分钟来计算。非常感谢!
解决方案
提高性能的关键是:
- 避免使用管道和 cmdlet,尤其是对于文件 I/O (
Get-Content
,Add-Content
)- 请改用该
System.IO.File
类型的方法。
- 请改用该
- 避免在 PowerShell 代码中循环。
- 取而代之的是链式数组感知运算符,例如
-match
and-replace
- 您已经在做的。 - 合并您的正则表达式以减少
-replace
调用次数。 - 使用预编译的正则表达式。
- 取而代之的是链式数组感知运算符,例如
把它们放在一起:
# Create precompiled regexes.
# Note: As written, they make the matching that -replace performs
# case-*sensitive* (and culture-sensitive),
# which speeds things up slightly.
# If you need case-*insensitive* matching, use option argument
# 'Compiled, IgnoreCase' instead.
$reMatch = New-Object regex '\bDownloaded\b', 'Compiled'
$reReplace1 = New-Object regex 'Downloaded |Traces from |\[', 'Compiled'
$reReplace2 = New-Object regex '\]:\s', 'Compiled'
$reReplace3 = New-Object regex ',.*', 'Compiled'
# The platform-appropriate newline sequence.
$nl = [Environment]::NewLine
foreach ($f in $files) {
$date = $f.BaseName.Substring(22,8)
# Read all lines into an array, filter and replace, then join the
# resulting lines with newlines and append the resulting single string
# to the log file.
[IO.File]::AppendAllText($PWD.ProviderPath + '/CleanedLogs.txt',
([IO.File]::ReadAllLines($f.FullName) -match
$reMatch -replace
$reReplace1 -replace
$reReplace2, ' ' -replace
$reReplace3, " $date" -join
$nl) + $nl
)
}
请注意,每个文件必须作为一个行数组作为一个整体装入内存,再加上它的一部分(作为数组和单个多行字符串),其大小取决于过滤的行数。
推荐阅读
- javascript - 单击超链接后更改屏幕位置
- python - 我的 python 代码没有执行我编写的函数(程序)
- c - 标识符 wchar_t 未定义
- rxjs - RXJS 在事件触发时发出数组项
- json - 如何使用 jq 从 terraform 状态文件中提取特定字段?
- python - Jupyter 没有执行暂存器单元
- apache-spark - 运行依赖于另一个任务的 Luigi 任务
- java - 将 Firebase Auth 从 Android SDK 切换到 Firebase Admin SDK
- django-rest-framework - 如何根据 Django Rest Framework 中的 JWT 有效负载覆盖 GET 方法?
- c# - C#元组不保留名称,只使用'itemx'