循环内的多个开关值
Multiple switch values inside a loop
我正在尝试编写一个在同一情况下匹配多个整数的 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
中,我想知道这是否意味着 $_
指的是循环而不是开关? 运行 出于想法,任何建议将不胜感激。如果有帮助,我想我是 运行 PowerShell 4。谢谢
新建
好的,我明白你想做什么。
因此,事实证明,Where-Object 的工作方式是您可以放置一个过滤器块,就像在 ForEach-Object 中一样,如果过滤器发出对象,则匹配的对象会继续沿着管道向下移动。
话虽如此,我认为这会 更 更简单作为目录 |在哪里 | ForEach,而不是这个复杂得多的 mega-Where you've got going on.
在您的示例中,您有一个正则表达式来查找其中包含 2 到 4 位数字的文件。如果文件包含数字 291 或 292,则您不想处理它们。
为了复制这个,我有一个充满 ISO 文件的目录,名为 290.iso、291.iso、292.iso 等等。
如果这有效,我们应该会看到在管道末尾返回的 ISO 列表,减去带有 'offending' 数字的那些,这是我们不想要的。
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-Object 的一种奇怪用法,老实说,我不确定它试图完成什么。我发现如果您能解释您的代码想要做什么,您总会在这里得到更好的答案。
也就是说,如果我将您的 Where-Object 更改为 ForEach-Object,这对我有用。
从功能上讲,您的开关有效。当我用这个代码结构测试时:
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-Object,我很乐意学习它,所以请告诉我:)
您必须将要匹配的开关值转换为数组。这可以使用 @ 字符来完成 例如,此代码
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
我正在尝试编写一个在同一情况下匹配多个整数的 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
中,我想知道这是否意味着 $_
指的是循环而不是开关? 运行 出于想法,任何建议将不胜感激。如果有帮助,我想我是 运行 PowerShell 4。谢谢
新建
好的,我明白你想做什么。
因此,事实证明,Where-Object 的工作方式是您可以放置一个过滤器块,就像在 ForEach-Object 中一样,如果过滤器发出对象,则匹配的对象会继续沿着管道向下移动。
话虽如此,我认为这会 更 更简单作为目录 |在哪里 | ForEach,而不是这个复杂得多的 mega-Where you've got going on.
在您的示例中,您有一个正则表达式来查找其中包含 2 到 4 位数字的文件。如果文件包含数字 291 或 292,则您不想处理它们。
为了复制这个,我有一个充满 ISO 文件的目录,名为 290.iso、291.iso、292.iso 等等。
如果这有效,我们应该会看到在管道末尾返回的 ISO 列表,减去带有 'offending' 数字的那些,这是我们不想要的。
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-Object 的一种奇怪用法,老实说,我不确定它试图完成什么。我发现如果您能解释您的代码想要做什么,您总会在这里得到更好的答案。
也就是说,如果我将您的 Where-Object 更改为 ForEach-Object,这对我有用。
从功能上讲,您的开关有效。当我用这个代码结构测试时:
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-Object,我很乐意学习它,所以请告诉我:)
您必须将要匹配的开关值转换为数组。这可以使用 @ 字符来完成 例如,此代码
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