【问题标题】:Powershell - If statement to validate foreach replace scriptPowershell - If 语句验证 foreach 替换脚本
【发布时间】:2012-10-02 08:44:42
【问题描述】:

请注意:我是 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

【问题讨论】:

    标签: powershell if-statement for-loop foreach


    【解决方案1】:

    -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”。

    【讨论】:

    • 我想我没有看到如何在没有 for 循环循环的情况下将所有其他变量($i 和 $a)放入循环中。我使用 for 循环中的 $i 变量循环访问各种 $varName 变量以匹配它是否包含该值。我不能简单地将 for 查找放在 else 语句中以循环遍历 $varName 和 $varValue 变量,因为它不会包含在 IF 部分中。我也不清楚我上面的两个例子中的哪一个是基于这个的。
    • 在您声明“我使用以下代码进行此操作:”之后,我从您的代码中获取了 -creplace 更改。用正则表达式替换不起作用吗?
    • 不,它不起作用。下面,两个不带下划线的“slct”实例和不带下划线的“btn”实例应该被替换。什么都没有被替换。 slct ahdfjhafkhsdjk slct fdahjkflhs slct fadshkjadsh _slct 这是对 slct 是否有效的测试。 _slct 会被替换吗? btn btn 我将这一行改为: ForEach-Object { $ -creplace "(?
    • 我猜我做错了什么?我做了这个测试:$string = "this is _test to see if test works" $var1 = "test" $var2 = "WIN" $test = $string -creplace "(?&gt;!_)" + $var1,$var2 Write-Host $test,结果和初始字符串一样。
    • @EustaceMonk 检查正则表达式!是"(?&lt;!_)" 而不是"(?&gt;!_)"
    猜你喜欢
    • 1970-01-01
    • 2021-08-27
    • 1970-01-01
    • 1970-01-01
    • 2012-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    相关资源
    最近更新 更多