【问题标题】:Are nested loops and if statements allowed in PowerShell?PowerShell 中是否允许嵌套循环和 if 语句?
【发布时间】:2020-12-27 11:33:11
【问题描述】:

我可以对 PowerShell 中的嵌套循环使用一些帮助。我有一个包含项目名称的文档。我有一个充满图像的文件夹。我正在遍历项目名称并测试该项目是否有任何图像。一个项目只会在文档中列出一次,但它可能有多个图像。例如,文档中的 ItemXYZ 可能在 images 文件夹中有 ItemXYZ、ItemXYZ_1 和 ItemXYZ_2。此代码适用于我正在尝试做的事情:

for ($i=2; $i -le $rowCount; $i++) {
    Write-Host -NoNewline ("Checking line $i of $rowCount`n")
    $item = $worksheet.Cells.Item($i,1).Text  #Item(row,column)
    foreach ($image in $images) {
        if ($item -eq $image.BaseName) {
            $worksheet.Cells.Item($i,21).Value = $hyperlinkchunk1 + $image.FullName + $hyperlinkchunk2 + $image.Name + $hyperlinkchunk3
            Write-Host ("** MATCH **")
        }
        for ($x=1; $x -le 12; $x++) {
            if ($item+'_'+$x -eq $image.BaseName) {
                $z = $x+21
                $worksheet.Cells.Item($i,$z).Value = $hyperlinkchunk1 + $image.FullName + $hyperlinkchunk2 + $image.Name + $hyperlinkchunk3
                Write-Host ("** MATCH **")
            }
        }
    }
}

项目的第一个图像将始终只是基本名称,因此如果第一个不存在,则无需检查 12 个下划线图像。因此,我想将嵌套的 for 语句放在第一个 if 语句中(下面更新了代码块)。这让我想到了这个问题。当我进行此调整时,我没有使用第一块代码找到所有匹配项。知道为什么吗?

for ($i=2; $i -le $rowCount; $i++) {
    Write-Host -NoNewline ("Checking line $i of $rowCount`n")
    $item = $worksheet.Cells.Item($i,1).Text  #Item(row,column)
    foreach ($image in $images) {
        if ($item -eq $image.BaseName) {
            $worksheet.Cells.Item($i,21).Value = $hyperlinkchunk1 + $image.FullName + $hyperlinkchunk2 + $image.Name + $hyperlinkchunk3
            Write-Host ("** MATCH **")
            

            for ($x=1; $x -le 12; $x++) {
                if ($item+'_'+$x -eq $image.BaseName) {
                    $z = $x+21
                    $worksheet.Cells.Item($i,$z).Value = $hyperlinkchunk1 + $image.FullName + $hyperlinkchunk2 + $image.Name + $hyperlinkchunk3
                    Write-Host ("** MATCH **")
                }
            }


        }        
    }
}

【问题讨论】:

  • 在我看来,您从第一次嵌套的第二个 for/if 语句返回“** MATCH **”,但是一旦嵌套在前面的 if 语句中,您就会返回没有。很可能第一个 if 语句的评估结果不正确。尝试使用执行 Write-Host 的不同值的 if 语句进行测试,而不是使用相同的“MATCH”字符串。这样你就知道哪个返回了 true。
  • 一个问题是您从 2 开始并转到 $rowcount。所以假设你有 5 行,当你真的需要 2..6 时它会变成 2..5

标签: powershell for-loop if-statement foreach nested


【解决方案1】:

我在您的代码本身中没有看到任何会阻止它按您期望的方式工作的内容。 Andrew Davis 可能走在正确的轨道上,他的评论是您的一些原始匹配来自循环而不是 If 语句,并且您加载到脚本中的信息有点偏离。我会说先检查那些。

如果您仍然遇到问题,不妨尝试在 If 语句中放置一个检查变量并使用它来控制循环。

foreach ($image in $images) {
        
        $match = $false

        if ($item -eq $image.BaseName) {
            $worksheet.Cells.Item($i, 21).Value = $hyperlinkchunk1 + $image.FullName + $hyperlinkchunk2 + $image.Name + $hyperlinkchunk3
            Write-Host ("** MATCH **")
            
            $match = $true
        }
        
        if ($match = $true) {
            for ($x = 1; $x -le 12; $x++) {
                if ($item + '_' + $x -eq $image.BaseName) {
                    $z = $x + 21
                    $worksheet.Cells.Item($i, $z).Value = $hyperlinkchunk1 + $image.FullName + $hyperlinkchunk2 + $image.Name + $hyperlinkchunk3
                    Write-Host ("** MATCH **")
                }
            }
        }
    }

显然,在第一个 If 语句中包含循环是更可取的,但这个选项也可以工作。

【讨论】:

    猜你喜欢
    • 2015-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多