【问题标题】:How can I make my powershell script for parsing faster?如何使我的 powershell 脚本更快地解析?
【发布时间】:2022-01-06 05:06:35
【问题描述】:

我有这个 PowerShell 脚本来一次解析许多看起来像配置文件的文本文件(大约 1 MB):

脚本:

$counter = ($false,0,0)
$objcounter = 0
$global:files = [ordered]@{}
$txt = [System.IO.File]::ReadAllLines($opath)

foreach($line in $txt){
    if ($counter[2] -eq "spline"){if ($counter[1] -eq 1){$counter[1]++}else{$key=$global:files.Keys;if (-not($global:files.Contains($line))){$global:files+=[ordered]@{$line=@{path=$line;type="spline"}}};$counter = ($false,0,0)}}
    elseif ($counter[2] -eq "object"){if ($counter[1] -eq 1){$counter[1]++}else{$key=$global:files.Keys;if (-not($global:files.Contains($line))){$global:files+=[ordered]@{$line=@{path=$line;type="sceneryobject"}}};$counter = ($false,0,0)}}
    elseif ($counter[2] -eq "splineh"){if ($counter[1] -eq 1){$counter[1]++}else{$key=$global:files.Keys;if (-not($global:files.Contains($line))){$global:files+=[ordered]@{$line=@{path=$line;type="splineh"}}};$counter = ($false,0,0)}}
    elseif ($counter[2] -eq "attachedobject"){if ($counter[1] -eq 1){$counter[1]++}else{$key=$global:files.Keys;if (-not($global:files.Contains($line))){$global:files+=[ordered]@{$line=@{path=$line;type="attachedobject"}}};$counter = ($false,0,0)}}
    elseif ($counter[2] -eq "splineattachement"){if ($counter[1] -eq 1){$counter[1]++}else{$key=$global:files.Keys;if (-not($global:files.Contains($line))){$global:files+=[ordered]@{$line=@{path=$line;type="splineattachement"}}};$counter = ($false,0,0)}}

    if ($line -eq "[spline]"){
        $counter = @($true,1,"spline");$objcounter++} 
    if ($line -eq "[splineh]"){
        $counter = @($true,1,"object");$objcounter++}
    if ($line -eq "[object]"){
        $counter = @($true,1,"object");$objcounter++}
    if ($line -eq "[attachObj]"){
        $counter = @($true,1,"attachedobject");$objcounter++}
    if ($line -eq "[splineAttachement]"){
        $counter = @($true,1,"splineattachement");$objcounter++}
}

(我知道它的结构不好。)

文件:

[spline]
0
apath\path\file3.ext
8947
8946
8992
0.0584106412565594
0.250000081976033
195.973568100565
90.0000020235813
39.99999937227
0
0
0
0
0
0
0
180.853118555128


[spline_h]
0
apath\path\file2.ext
8949
8948
9022
0.0565795901830857
0.250000202235118
202.972286028874
90.0000020235813
39.99999937227
0
0
0
0
0
0
0
183.907441598005
mirror

[spline]
0
apath\path\file.ext
8951
0
9019
0.0585327145350332
0.0999999434550936
201.971026072961
90.0000020235813
39.99999937227
0
0
0
0
0
0
0
183.47110728047
mirror

(等等……)

脚本运行良好,但解析文件需要很长时间,一段时间后我得到“无响应”并且应用程序崩溃。

这是我需要的输出:

$global:files = [ordered]@{path=@{path="path";type="type"}}

其中“路径”是文件路径,例如:apath\path\file.ext 和 'type' 是网格类型,例如:splinespline_h

我可以改变什么来加快解析速度?

【问题讨论】:

  • 您能否添加一个示例,说明您需要的输出是什么?对我来说,这还不清楚..
  • @Theo 当然。所需的输出是 [ordered]。
  • 您能否解释一下脚本在做什么以及它的条件是什么,此时我们可能能够以更有效的方式重新创建它,但if 条件似乎过于复杂。我知道这是一个哈希表,其中[..] 之间的每个关键字的paths 作为键,值是路径和关键字。
  • @Theo 我敢肯定,到目前为止,您将能够改进我的答案,尤其是在 regex 部分,尽管 OP 之前需要澄清某些点

标签: powershell text-parsing


【解决方案1】:

这是一个示例,说明如何主要使用regex 和一些字符串操作来改进它。请注意,我对它还差得很远,我很确定它可以大大改进,但它对我有用。

我不清楚当有两个或多个类型 ([keyword]) 具有相同的路径(路径是 hashtable 键)时会发生什么。现在代码假设文件中不会有重复的路径。

对于regex 的解释,请参阅:https://regex101.com/r/aN4WNR/1
注意: 这仅适用于路径以 .ext 结尾,如果不是这种情况,您也应该澄清这一点.

regex 期望多行字符串正常工作,因此您需要使用其中任何一个(这也将提高脚本的效率)。

  • Get-Content -Raw
  • [System.IO.File]::ReadAllText(...)
$txt = Get-Content -Raw ./test.txt
$re = [regex]::Matches($txt, '(?ms)\b(?<=(\[)).*?\.ext\b')
$result = [ordered]@{}

foreach($r in $re)
{
    $parse = $r.Value -split '\r?\n'
    $type = $parse[0].Replace(']','')
    $path = $parse[-1]

    $result.Add(
        $path,
        [ordered]@{
            path = $path
            type = $type
        }
    )
}

结果:

PS /> $result

Name                           Value
----                           -----
apath\path\file3.ext           {path, type}
apath\path\file2.ext           {path, type}
apath\path\file.ext            {path, type}

PS /> $result['apath\path\file2.ext']

Name                           Value
----                           -----
path                           apath\path\file2.ext
type                           spline_h

【讨论】:

  • @jjb 那么好吧,如果你的脚本执行得这么快,为什么要问这个问题呢?
  • 问题是我有大约50个或更多的文件需要解析,而对于每个文件,2分钟是很长的时间。编辑:我第二次检查了速度,你的脚本需要比我的多 30 秒。我的最后一条评论是错误的,因为我已经用Get-Content -Raw 检查了脚本,但没有给我任何输出......
猜你喜欢
  • 1970-01-01
  • 2012-07-01
  • 2013-04-18
  • 1970-01-01
  • 2019-07-30
  • 2016-01-13
  • 2023-03-16
  • 2017-04-11
  • 1970-01-01
相关资源
最近更新 更多