【问题标题】:Issue with nested powershell嵌套PowerShell的问题
【发布时间】:2018-02-20 15:23:36
【问题描述】:

我有这个代码sn-p,我尝试在一个目录的所有文件中替换一些字符串。我以为我可以将 foreach 嵌套在 ForEach-Object 中,但这似乎不起作用。

我得到的错误是:

InvalidArgument: (:) [ForEach-Object], ParameterBindingException


$files = Get-ChildItem $testdir\reference *.* -recurse
$replacementMap = @{"Fruit::Apple" = "NewApple";"Fruit::Banana" = "NewBanana"}

foreach ($file in $files)
    {
    If (Get-Content $($file.FullName) | Select-String -Pattern "Fruit::")
        {
        $content = Get-Content $($file.FullName) | ForEach-Object
               { 
               $line = $_
               foreach ($entry in $replacementMap.GetEnumerator())
                   {
                   $line -replace $($entry.Name),$($entry.Value)
                   }
                }
        $content = $content -join "`r`n"
        $content | Set-Content $($file.FullName)
     }

此代码在没有

的情况下工作
foreach ($entry in $replacementMap.GetEnumerator())
    {
    $line -replace $($entry.Name),$($entry.Value)
    }

部分。任何人都知道我做错了什么?提前致谢

【问题讨论】:

  • ForEach-Object cmdlet 和foreach(){} 循环是两种不同的语句。但是,您的问题似乎是 ForEach-Object{ 之间的换行符 - 将 { 向上移动到同一行

标签: powershell foreach nested


【解决方案1】:

您错过了 foreach 对象上的花括号闭包和格式问题。您需要以不同的方式处理 foreach 和 foreach-object:

用这个替换你现有的 foreach 部分:

foreach ($file in $files)
{
    If(Get-Content $($file.FullName) | Select-String -Pattern "Fruit::")
    {
        $content = Get-Content $($file.FullName) | %{ 
                   $line = $_
                   foreach ($entry in $replacementMap.GetEnumerator())
                   {
                    $line -replace $($entry.Name),$($entry.Value)
                   }
        }
        $content = $content -join "`r`n"
        $content | Set-Content $($file.FullName)
    }
}

【讨论】:

    【解决方案2】:

    不是逐行处理文件,而是一次对整个文件内容执行替换操作。如果内容有变化,覆盖文件。

    $replacementMap = @{
        "Fruit::Apple" = "NewApple"
        "Fruit::Banana" = "NewBanana"
    }
    
    Get-ChildItem $testdir\reference -File -Recurse | foreach {
        $content = Get-Content $_
        $dirty = $false
        foreach ($key in $replacementMap.Keys) {
            $content = $content -replace $key,$replacementMap.$key
            $dirty = $true
        }
        if ($dirty) { $content | Set-Content $_ }
    }
    

    【讨论】:

    • 这将如何影响文件中的换行符?我现在的方法的一个已知问题是它可能会改变行尾
    • 它根本不会影响换行符,除非您将换行符放入搜索模式中。
    • 非常感谢,我以后就用这个方法了!
    • 它也应该比 line-wise 方法快很多。
    • 好像有问题,替换不行。当我的替换映射中有两个条目时,替换似乎只发生一次(我在 foreach 循环中添加了一个弹出窗口,它只触发一次)。在弹出窗口中显示 $_.Name 的值时,字符串为空。知道这怎么可能吗?
    猜你喜欢
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-17
    • 1970-01-01
    相关资源
    最近更新 更多