1

请注意:我是 powershell 的新手,但我编写了几个简单的脚本来产生我需要的结果;然而,这个我似乎无法解开(或谷歌)!

我正在尝试编写一个脚本,它将遍历 HTML 文件的内容并用新的文本字符串替换特定的文本字符串。但是,如果找到的字符串与不应被替换的特定字符串类型匹配,则不会被替换。

让我给你整个设置:

$filePath = "C:\test.htm"
$fileContents = Get-Content $filePath

#Get the variable list values
$varList = Get-Content "C:\list_of_variables_to_be_searched.txt"

#The C:\list_of_variables_to_be_searched.txt" file contains the variable name, then a
 period, then the replace value. For example, slct.<html information to replace
 where "slct" is found>.
#Assign each element split by the period into a single array
$arrayMix = @()

foreach ($var in $varList)
{
    $z = $var.split(".")
    $arrayMix += $z
}

#Split the arrayMix into two other arrays (varName and varValue)
$varName = @()
$varValue = @()

for ($i = 0; $i -le $arrayMix.Length-1; $i++)
{
    if ($i % 2 -eq 0) # Finds even numbers
    {
        $arrayMix[$i].Trim()
        $varName += $arrayMix[$i]
    }
    else
    {
        $arrayMix[$i].Trim()
        $varValue += $arrayMix[$i]
    }
}

现在我要做的是搜索 $fileContents 的每一行,搜索数组中的每个 varName 并将其替换为 varValue。

我使用以下代码进行此工作:

for ($i = 0; $i -le $varName.Length-1; $i++)
{
    foreach ($line in $filePath)
    {
        (Get-Content $filePath) |
        ForEach-Object { $_ -creplace $varName[$i],$varValue[$i]} |
        Set-Content $filePath
    }
}

但是,在某些情况下,varName 之前可能带有下划线字符(例如,_slct)。这些正在使用上述脚本替换,这会导致问题。

我已经搜索并搜索了一种在 foreach 循环中使用 if/else 的方法,但是这些示例对解决这个问题没有帮助。

我首先尝试了这个:

foreach ($line in $fileContents)
{ 
    if ($line.Contains("slct_"))
    {
        continue
    }
    else
    {
        $line = {$_ -creplace $varName[1],$varValue[1]}
    }
}

但是,我相信对 Powershell 更有经验的人都知道,那是行不通的。

接下来我决定尝试将所有内容分解成数组,然后像这样循环遍历它们:

for ($i = 0; $i -le $fileContents.Length-1; $i++)
{
    if ($fileContents[$i].Contains("_{0}" -f $varName[$i]))
    {
        continue
    }
    else
    {
        $fileContents[$i] = $fileContents[$i] -creplace $varName[$a],$varValue[$a]
    }
}
Set-Content $filePath $fileContents

但是,同样,这也不起作用。有人可以指出我正确的方向吗?有没有办法在 foreach 循环中使用 if/else?或者有没有更好的方法我还没有学会?

谢谢!

更新:

我已经让它在测试中工作,但我无法让它在 foreach 循环中或当变量实际调用数组的特定索引时起作用。

$string = "this is _test to see if test works"
$var1 = "test"
$var2 = "WIN"

$test = [regex]::replace($string, '(?<!_)'+$var1, $var2)
Write-Host $test

尝试此操作时,根据以前的帖子,它没有任何作用:

$string = "this is _test to see if test works"
$var1 = "test"
$var2 = "WIN"

$test = $string -creplace "(?<!_)" $var1,$var2
Write-Host $text
4

1 回答 1

0

-creplace 进行正则表达式匹配,并且使用正则表达式,您可以在后面使用否定的外观说“仅当它没有被某些东西处理时才匹配”。例如这个正则表达式:

(?<!_)Test

说“仅当它前面没有 _ 时才匹配测试”。因此,尝试将您的 -creplace 子句更改为:

-creplace "(?<!_)" + $varName[$i], $varValue[$i]

仅当 varName 前面没有下划线时才匹配它。

http://www.regular-expressions.info/是一个很好的网站,可以了解更多关于正则表达式的信息,包括背后的负面看法。

至于在 foreach 中执行 if/else,您可以将 if/else 语句放在脚本块中,例如

$input | ForEach-Object { if ($_ -eq "Test") { "X" } else { "Y" } }

如果输入行是“Test”,则输出“X”,否则输出“Y”。

于 2012-10-11T16:14:14.363 回答