Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Powershell 循环内的多个开关值_Powershell_Switch Statement_Powershell 4.0 - Fatal编程技术网

Powershell 循环内的多个开关值

Powershell 循环内的多个开关值,powershell,switch-statement,powershell-4.0,Powershell,Switch Statement,Powershell 4.0,我正在尝试编写一个switch语句,在同一情况下匹配多个整数。我尝试了许多不同的例子,最近的例子是: Get-ChildItem $folder -Filter "*.$($extension)" | Where-Object { $name = $_.Name $pattern = '(\d{2,4})' $metric = ([regex]$pattern).Matches($name) $variable = $metric.Item(0) sw

我正在尝试编写一个switch语句,在同一情况下匹配多个整数。我尝试了许多不同的例子,最近的例子是:

Get-ChildItem $folder -Filter "*.$($extension)" | Where-Object {

    $name = $_.Name
    $pattern = '(\d{2,4})'
    $metric = ([regex]$pattern).Matches($name)
    $variable = $metric.Item(0)

    switch ($variable) {
        {291,292 -contains $_} {
            Write-Host "Skip these numbers...`n"
            break
        }
        default {
            #process other numbers
        }
    }
}
但是这似乎被跳过了,并且总是以默认位结束。在这之后,我找不到一种方法来点击这两个神奇的数字并跳过其余的代码

这个switch语句在一个
Get ChildItem
中,我想知道这是否意味着
$\u
指的是循环而不是开关?没有想法了,任何建议都将不胜感激。如果有帮助的话,我想我正在运行PowerShell 4。谢谢

新的 好的,我明白你想做什么

Get-ChildItem $folder -Filter "*.$($extension)" | 
    Where-Object {$_.BaseName -match $pattern} |
         ForEach {
            #Dump the files is their name contains any of these numbers
            if ($_.BaseName -in (291,292)) {$null}
            else{$_}
            } | ForEach-Object {
                #Run your macros here
                }
因此,事实证明,对象的工作方式是,您可以放置一个过滤器块,就像在ForEach对象中一样,如果过滤器发出和对象,则匹配对象将继续沿着管道进行

话虽如此,我认为这将比Dir | Where | ForEach更简单,而不是像现在这样复杂得多

在您的示例中,有一个正则表达式在查找包含2到4位数字的文件。如果文件包含数字291或292,则不希望处理它们

为了复制这个,我有一个充满ISO文件的目录,名为290.ISO、291.ISO、292.ISO等等

如果这样做有效,我们应该在管道的末尾看到一个ISO列表,减去那些带有“冒犯”数字的,我们不想要的

Dir t:\ 2*.iso | Where {$_.BaseName -match $pattern} | ForEach-Object{
    if ($_.BaseName -in (291,292)) {$null}
    else{$_}
    } 
结果:

Mode                LastWriteTime         Length Name                                                                                                 
----                -------------         ------ ----                                                                                                 
-a----        12/1/2015  12:40 PM             12 290.iso                                                                                              
-a----        12/1/2015  12:40 PM             12 293.iso                                                                                              
-a----        12/1/2015  12:40 PM             12 294.iso                                                                                              
-a----        12/1/2015  12:40 PM             12 295.iso 
因此,在您的例子中,您只需在管道的末尾添加一个ForEach来处理这些宏或任何您想做的事情

Get-ChildItem $folder -Filter "*.$($extension)" | 
    Where-Object {$_.BaseName -match $pattern} |
         ForEach {
            #Dump the files is their name contains any of these numbers
            if ($_.BaseName -in (291,292)) {$null}
            else{$_}
            } | ForEach-Object {
                #Run your macros here
                }
可能更好的方法是收集我们希望在变量中使用的文件,然后在这些文件上使用ForEach

#Only return files with numbers in the name
$MatchingFiles = Get-ChildItem $folder -Filter "*.$($extension)" | 
    Where-Object {$_.BaseName -match $pattern} 

#Remove files with 291, 292 in their name   
$FilteredFiles = $MatchingFiles | 
         ForEach {
            #Dump the files is their name contains any of these numbers
            if ($_.BaseName -in (291,292)) {$null}
            else{$_}
            } 

#Run the macros for each file remaining            
ForEach ($file in $FilteredFiles){
    #Run your macros here
    }
我知道这不能回答你的转换问题,但我认为这是一个更好的方法。我不想继承你为完成这项任务而提出的工作开关

古老的 这是Where对象的一种奇怪用法,如果我可以完全诚实地说,我不确定这是为了实现什么。我发现,如果你能解释你的代码想要做什么,你总能在这里得到更好的答案

也就是说,如果我将Where对象更改为ForEach对象,这对我来说是有效的

从功能上讲,您的交换机可以正常工作。当我使用此代码结构进行测试时:

forEach ($variable in (290..295)){
switch ($variable) {
        {291,292 -contains $_} {
            Write-Host "Skip these numbers... $variable"
            break
        }
        default {
            "We won't skip this one $variable"#process other numbers
        }
    }

    }
输出:

We won't skip this one 290
Skip these numbers.... 291
Skip these numbers.... 292
We won't skip this one 293
We won't skip this one 294
We won't skip this one 295

因此,我认为问题在于您使用了错误的cmdlet来执行此任务。如果我错了,并且您有很好的理由使用Where对象,那么我很想学习它,因此请让我知道:)

您必须将开关值转换为匹配数组。这可以使用@字符作为示例来完成,代码如下

function checkSwitch($switchValue) {
    switch ($switchValue) {
        { @(291, 292) -contains $_ } {
            Write-Host "Case hit, moving on ..."
        }

        default {
            Write-Host "Nothing to see here"
        }
    }
}

checkSwitch 42
checkSwitch 291
checkSwitch 292
写入此输出

Nothing to see here
Case hit, moving on ...
Case hit, moving on ...

问题在于
$variable
是一个正则表达式匹配对象,而不是
[int]

试试像这样的东西

[int]$variable.Value

什么是$variable?它包含什么?你说的“在
获取子项中”是什么意思?你是说它在每个对象的
内部吗?请显示实际代码。$变量是通过正则表达式从文件名中提取的整数。让我添加更多关于$variable是如何构造的信息。为了说明它的价值,我使用$variable=291尝试了您的代码,结果很好。我们需要看到更多的代码。简短地回答一下,我认为所有文件都被返回的原因是,正则表达式匹配在PowerShell中非常嘈杂,并且总是返回一个对象,导致所有内容都出现在管道中。在我的新答案中,我提出了一种新的方法,以不同的方式解决问题。完全公正的评论,我对PowerShell和编写/更改位非常陌生。据我所知,我也不是专业程序员,只是尝试自动化一些手动工作。如果文件名中的数字匹配,循环将遍历包含excel电子表格的文件夹中的每个文件,并运行某些宏。(我不想在所有报告上运行宏)。我承认很多内容可能被遗漏了,因为我不想发布整个节目。刚刚看到你的新答案,非常感谢你花时间解释这一点。更愿意从整体上更好地处理解决方案。在第2版(从今天开始…!)中,我将考虑这一点。如何扩展第二部分,使其排除包含291或292的文件名,但不一定是它们的全部文件名?我将$u.BaseName-in(291292)更改为$u.BaseName-match“29(1 | 2)”,然后它就可以工作了。克里斯。不使用奇怪格式的简单方法是从使用-IN(检查项目是否与文件列表匹配)更改为使用-LIKE(允许进行通配符搜索)。