我在网络共享上有16000多个 list 日志文件,大小从3-5 KB不等。
示例文件如下所示:
## System Info
SystemManufacturer:=:Dell Inc.
SystemModel:=:OptiPlex GX620
SystemType:=:X86-based PC
ChassisType:=:6 (Mini Tower)
## System Type
isLaptop=No
我需要将它们放入数据库中,因此我开始对其进行解析,并为每个对象创建一个自定义对象,以便以后用于检查重复项,规范化等。
如下所示,使用代码片段进行的初始解析大约需要7.5分钟。
Foreach ($invlog in $invlogs) {
$content = gc $invlog.FullName -ReadCount 0
foreach ($line in $content) {
if ($line -match '^#|^\s*$') { continue }
$invitem,$value=$line -split ':=:'
[PSCustomObject]@{Name=$invitem;Value=$value}
}
}
我开始对其进行优化,经过几次尝试和错误后,结果耗时2分钟4秒钟:
Foreach ($invlog in $invlogs) {
foreach ($line in ([System.IO.File]::ReadLines("$($invlog.FullName)") -match '^\w') ) {
$invitem,$value=$line -split ':=:'
[PSCustomObject]@{name=$invitem;Value=$value} #2.04mins
}
}
我也尝试使用哈希代替PSCustomObject,但是令我惊讶的是,它花了更长的时间(5分26秒)
Foreach ($invlog in $invlogs) {
$hash=@{}
foreach ($line in ([System.IO.File]::ReadLines("$($invlog.FullName)") -match $propertyline) ) {
$invitem,$value=$line -split ':=:'
$hash[$invitem]=$value #5.26mins
}
}
在这里使用最快的方法是什么?
最佳答案
看看这是否更快:
Foreach ($invlog in $invlogs) {
@(gc $invlog.FullName -ReadCount 0) -notmatch '^#|^\s*$' |
foreach {
$invitem,$value=$line -split ':=:'
[PSCustomObject]@{Name=$invitem;Value=$value}
}
}
将-match和-notmatch运算符应用于数组时,它会返回满足匹配条件的所有元素,因此您可以不必为排除的行而测试每一行。
您是真的要为每一行创建一个PS对象,还是为每个文件创建一个PS对象?
如果您希望每个文件一个对象,请看这样是否更快:
多行正则表达式消除了行数组,并且使用过滤器代替foreach来创建哈希条目。
$regex = [regex]'(?ms)^(\w+):=:([^\r]+)'
filter make-hash { @{$_.groups[1].value = $_.groups[2].value} }
Foreach ($invlog in $invlogs) {
$regex.matches([io.file]::ReadAllText($invlog.fullname)) | make-hash
}
切换到使用多行正则表达式和[io.file]::ReadAllText]的目的是简化Powershell在内部使用文件输入进行的操作。 [io.file]::ReadAllText()的结果将是一个字符串对象,这是一种比[io.file]::ReadAllLines()产生的字符串数组简单得多的对象类型,并且所需的开销更少在内部进行组织。过滤器本质上只是一个函数的Process块-它会针对管道中的每个对象运行一次,因此它模仿了foreach-object的操作,但实际上运行速度略快(我不知道内部原理足以告诉您确切的原因)。这两个更改都需要更多的编码,并且只会导致性能的少量提高。在我的测试中,切换到多行文件每个文件大约获得0.1毫秒,然后从foreach-object更改为过滤器再增加0.1毫秒。与所需的其他编码工作相比,您可能看不到这些技术的使用率很高,因为它们的返回率很低,但是当您开始将这些毫秒的分数乘以160K迭代时,它就变得很重要。
关于powershell - 在PowerShell中解析数千个小文件的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20082369/