如何使此PowerShell脚本更高效?

时间:2017-12-05 20:55:11

标签: regex xml powershell

我正在尝试创建一个带有XML文件的脚本,查找匹配条件,如果它发现它添加了一行新的asteriks,那么当完成通过该文件去除它的所有XML标签并离开时纯文本文件中的数据。

该脚本已经在一个小的输入xml文件上进行了测试并且工作正常,但是当我将一个大型XML文件传递给它时需要花费很长时间(实际上并不确定我运行它的时间超过一个小时仍然没有结果所以我刚刚停止了它。)

我猜我必须以非常低效的方式执行这项工作,希望你们能帮我快速有效地工作。

以下是以下脚本:

# Takes input XML File, cleans up XML elements, outputs plain text file

$FileName = "C:\Users\someguy\Desktop\input.xml"
$Pattern = "ProcessSpecifier = ""true"""  
$FileOriginal = Get-Content $FileName

[String[]] $FileModified = @() 
Foreach ($Line in $FileOriginal)
{   
    $FileModified += $Line
    if ($Line -match $Pattern) 
    {
        #Add Lines after the selected pattern 
        $FileModified += "*************isActive=true*****************"      
    } 
}


$FileModified -replace "<[^>]+>", "" | Out-File C:\Users\someguy\Desktop\Output.txt

2 个答案:

答案 0 :(得分:3)

让我们来看看后面和一堆正则表达式来加速这里的事情。此外,我不打算将整个内容存储在内存中,我只是将它传递给管道,这应该有所帮助。我从行的开头和末尾删除空格,并过滤掉空行,但如果需要,可以删除该位。

# Takes input XML File, cleans up XML elements, outputs plain text file

$FileName = "C:\Users\someguy\Desktop\input.xml"
$Pattern = '(?<=^.*ProcessSpecifier = "true".*$)'
(Get-Content $FileName) -replace $Pattern, "`n*************isActive=true*****************" -replace '<[^>]+?>' -replace '^\s*|\s$' | ?{$_} | Set-Content C:\Users\someguy\Desktop\Output.txt

所以,这里最重要的是我用后面的方法找到你的模式文本,然后在该行添加一个新行和星号行。那条线

    <SomeTag>ProcessSpecifier = "true"</SomeTag>

变为:

    <SomeTag>ProcessSpecifier = "true"</SomeTag>`n*************isActive=true*****************

在双引号中使用时,反引号`后跟n会创建一个新行,所以&#39; ************* isActive = true ********* ********&#39;紧跟在搜索模式行之后就是它自己的行。过去我删除XML标签,然后从任何行删除任何前导或尾随空格。

在RegEx替换后,我将结果传递给删除空行的Where语句,然后将剩余的行传递给Set-Content,我发现其性能优于Out-File 1}}。

答案 1 :(得分:1)

TheMadTechnician答案的变化:

# Takes input XML File, cleans up XML elements, outputs plain text file

$FileName = "C:\Users\someguy\Desktop\input.xml"
$Pattern = '(?<=^.*ProcessSpecifier = "true".*$)'
Set-Content -Path C:\Users\someguy\Desktop\Output.txt -Value (((Get-Content $FileName) -replace $Pattern, "`n*************isActive=true*****************" -replace '<[^>]+?>' -replace '^\s*|\s$').Where{$_})

我实际上试图避开管道,它是相当缓慢的afaik。当然,如果文件非常大,你会遇到内存消耗问题。 “(。。Where”构造不适用于所有PowerShell版本(版本4+ iirc)。

这是猜测,我不确定这实际上是否比TheMadTechnician更快。我对结果感到好奇:)

相关问题