【问题标题】:Powershell foreach loop through a list that is split from user inputPowershell foreach 循环遍历从用户输入中拆分出来的列表
【发布时间】:2021-07-16 10:00:03
【问题描述】:

我这里有这个 for 循环:

$fromInput = 1
$toInput = 99

for ($i = $fromInput; $i -le $toInput; $i++) {
            
    $destinationDir = '\\pc' + '{0:d5}' -f @($i) + "\$shareName\$dupDir"
    $netUseDir = '\\pc' + '{0:d5}' -f @($i) + "\$shareName"
    $passObj = 'pass@' + '{0:d3}' -f @($i)
        
    }

所以它会循环从 1 到 99 的 PC,但我现在需要的是循环遍历用户输入的拆分数字列表

我正在尝试使用 foreach 循环来做到这一点,但它不像 for 循环中的那样对我有用:

$userInput = Read-Host "Input numbers divided by a comma [", "]"
$numberList = $userInput.split(", ")

foreach ($i in $numberList) {

    $destinationDir = '\\pc' + '{0:d5}' -f @($i) + "\$shareName\$dupDir"
    $netUseDir = '\\pc' + '{0:d5}' -f @($i) + "\$shareName"
    $passObj = 'pass@' + '{0:d3}' -f @($i)

    }

如何创建一个获取 $userInput 的 foreach 循环,将其拆分为 $numberList,然后按照上面显示的方式为 $numberList 中的每个数字循环。 非常感谢您一如既往的帮助!

【问题讨论】:

  • 如果我理解正确,那么您只需将 for 更改为 foreach
  • “但它不像 for 循环中的那样对我有用” - 那么,它是如何工作的?你是唯一能看到你屏幕的人,请不要让我们猜测你的问题是什么:-)
  • 好吧,抱歉,忘记提了。它的工作方式是它不会将 0-s 附加到共享名称位置的 conc 中。意思是当用户输入 1, 2, 3... 完整共享名称的 conc 应该是 '\\pc00001\$shareName\$dupDir' 而不是这样: "'\\pc1\$shareName\$dupDir '。在 for 循环中,串联是应该的。
  • 我已经修复了 for / foreach 问题以防止分心,因为第二个循环的真正问题是 缺少零填充格式化字符串中的数字。

标签: powershell foreach string-formatting


【解决方案1】:

主要问题是您将格式设置 (d5) 应用于用于整数类型的字符串。您可以简单地转换为[int] 以获得所需的结果。

foreach ($i in $numberList) {

    $destinationDir = '\\pc' + '{0:d5}' -f [int]$i + "\$shareName\$dupDir"
    $netUseDir = '\\pc' + '{0:d5}' -f [int]$i + "\$shareName"
    $passObj = 'pass@' + '{0:d3}' -f [int]$i

    }

Read-Host 将数据读取为[string]。如果该数据出于某种原因需要为不同的类型,则需要进行隐式或显式转换。

【讨论】:

    【解决方案2】:

    首先,对于用户输入,我建议您使用如下内容:

    $userInput = Read-Host "Input numbers divided by a comma [", "]"
    try
    {
        [int[]]$numberList = $userInput.split(',')
    }
    catch
    {
        'Input only numbers separated by commas.'
        break
    }
    

    解释为什么有[int[]] 以及为什么有try {...} catch {...} 声明:

    我们正在尝试将string 转换为array,并将生成的元素转换为int。因此,我们应该得到一个整数数组,如果不是这种情况,这意味着如果用户输入的内容与用逗号分隔的数字不同,我们将得到一个错误,该错误由catch 块捕获和处理。

    在这种情况下,需要通过一个简单的示例将字符串转换为整数:

    PS /> '{0:d5}' -f '1' # String formatting on a string
    1
    
    PS /> '{0:d5}' -f 1 # String formatting on an integer
    00001
    

    现在对于循环,这里是我看到的 3 个简单的替代方案:

    • 带有for循环:
    for($i=$numberList[0];$i -le $numberList.Count;$i++)
    {
        $destinationDir = "\\pc{0:d5}\$shareName\$dupDir" -f $i
        $netUseDir = "\\pc{0:d5}\$shareName" -f $i
        $passObj = 'pass@{0:d3}' -f $i
    }
    
    • 带有foreach循环:
    foreach($i in $numberList)
    {
        $destinationDir = "\\pc{0:d5}\$shareName\$dupDir" -f $i
        $netUseDir = "\\pc{0:d5}\$shareName" -f $i
        $passObj = 'pass@{0:d3}' -f $i
    }
    
    • 带有ForEach-Object循环:
    $numberList | ForEach-Object {
        $destinationDir = "\\pc{0:d5}\$shareName\$dupDir" -f $_
        $netUseDir = "\\pc{0:d5}\$shareName" -f $_
        $passObj = 'pass@{0:d3}' -f $_
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-25
      • 2018-09-15
      • 2021-06-28
      • 1970-01-01
      • 2014-07-13
      • 1970-01-01
      相关资源
      最近更新 更多