Powershell 解析脚本永远不会结束
我有下面的脚本,但它永远不会停止执行 可能是什么问题?我试图调试它,但显然它可以正确地处理单个文件,但当我将它扔到一个充满内容的文件夹时失败了Powershell 解析脚本永远不会结束,powershell,parsing,infinite-loop,Powershell,Parsing,Infinite Loop,我有下面的脚本,但它永远不会停止执行 可能是什么问题?我试图调试它,但显然它可以正确地处理单个文件,但当我将它扔到一个充满内容的文件夹时失败了 $path = split-path -parent $MyInvocation.MyCommand.Definition $files = Get-ChildItem "$path\CodeForCertification\5_SourceCode\*" -Include *.c,*.h -Recurse | where{ ! $_.
$path = split-path -parent $MyInvocation.MyCommand.Definition
$files = Get-ChildItem "$path\CodeForCertification\5_SourceCode\*" -Include *.c,*.h -Recurse | where{
! $_.PSIsContainer
}#$PSScriptRoot
ForEach ($file in $files){
$data = Get-Content -Path $file.FullName
$feature = Get-Content "$path\Disabled_Features.txt"
#[System.ArrayList]$Modifier
$nl=[Environment]::NewLine
$Modifier=@()
$flag=0
$data = $data | ForEach-Object -Begin {
$ignore = $false; $levels = 0
} -Process {
for($counter=0; $counter -lt $feature.Count; $counter++){
$parse = $feature[$counter]
if($_ -match "^#ifdef $parse" -And $flag -eq '0') {
$ignore = $true
$flag = 1;
}
}
if($ignore) {
if ($_ -match "^#ifdef") {
$levels++
}elseif ($_ -match "#endif") {
if($levels -ge 1) {
$levels--
if($levels -eq '0'){
$ignore = $false
}
}
}
}else {
$flag=0
$temp=$_
$_
$Modifier+="$temp"
}
}
$data | Out-File $file.FullName
}
好的,Jackson,在您输入某种问题垃圾邮件过滤器之前,让我们先解决您的问题;-) 考虑一下(只需将其放在脚本开头的某个地方):
是的,为什么不呢?…你有一些我们可以测试的样本文件吗?您的禁用功能和删除的源代码文件?您是否尝试在文件之间插入一些输出行,以便知道它正在继续?你如何衡量缺乏进展的循环?如果有更好的方法,最好知道这段代码应该做什么。您是否在PowerShell ISE中使用断点进行调试?您的代码可能很慢,部分原因是您在每次迭代时都会重新读取txt文件,并在默认模式下使用Get Content,这在包含大量行的大型文件中非常慢。txt文件只包含多行条目,例如STRING1 STRING2(在单独的行中)而源代码只是一些.c文件,其中包含段落#ifdef STRING2“代码块”#endif,例如。我担心这只是一种缓慢的方法。我欣赏优化。是的,我用带断点的ISE powershell进行了调试。谢谢,周一经过几次修改后,我会给你一个反馈。谢谢你,托尼。仅供参考,-In无法获取值,因此我必须对功能匹配使用-Contain运算符。好的,要使
-In
起作用,右侧必须是数组,左侧必须是该数组中包含的逐字逐句。如果您获得一个功能列表,其中包含一个文件的简单get Content
,其中每个功能都是一行(但要注意额外的空格),则应该是这种情况。-contains
运算符的工作原理完全相同,只是左右侧交换(数组左侧,搜索值右侧)。所以我有点困惑你是怎么解决的,但只要它有效。。。
function RemoveUndesiredFeatures([string[]]$lines,[string[]]$undesiredFeatures)
{
$inIgnoreBlock = $false
$nestingLevel = 0
foreach ($line in $lines)
{
if ($inIgnoreBlock)
{
# Only search for nested blocks and end of block
if ($line -like "#ifdef*")
{
$nestingLevel++
}
elseif ($line -like "#endif*")
{
$nestingLevel--
}
if ($nestingLevel -eq 0)
{
$inIgnoreBlock = $false
}
}
else
{
# Search for undesired feature
$isIfdefMatch = $line -match "#ifdef (?<feature>\w+)"
if ($isIfdefMatch -and ($Matches.feature -in $undesiredFeatures))
{
# Ignore Feature
$inIgnoreBlock = $true
$nestingLevel++
}
else
{
# Output line
$line
}
}
}
}
$undesiredFeatures = @("F1","F2") # Just as example. Get-Content on a file with features is also fine
$files = Get-ChildItem *.c,*.h -Recurse # Again, just as example
foreach ($file in $files)
{
$lines = Get-Content $file.FullName
$changedLines = RemoveUndesiredFeatures $lines $undesiredFeatures
if ($changedLines.Count -ne $lines.Count)
{
# Features were removed. Write out changed file (to a different file to preserve my test files)
Set-Content -Value $changedLines -Path "$($file.FullName).changed"
}
}