组合多个逻辑运算符
Combine multiple logical operators
有没有办法在 where 语句中组合多个逻辑运算符的参数?
基本上我有这样的说法:
<command chain> | where {$_.user.tostring() -ne "USER1" -and $_.user.tostring() -ne "USER2" -and $_.user.tostring() -ne "USER3"}
其实是一个比较长的链,所以我想把它简化成这样:
<command chain> | where {$_.user.tostring() -ne {"USER1" -or "USER2" -or "USER3"}}
以上说法不成立,请问有什么建议吗?
您想使用这个:
where {$_.user.tostring() -notin ("USER1","USER2","USER3")}
或者这个:
where {($_.user.tostring() -ne "USER1") -and ($_.user.tostring() -ne "USER2") -and ($_.user.tostring() -ne "USER3") }
这真的很简单。通常,布尔运算符应该只用于组合比较运算符(或您知道的其他表示布尔值的东西)。
您的代码:
where {$_.user.tostring() -ne {"USER1" -or "USER2" -or "USER3"}}
这根本就是废话。它总是会评估为真。 {"USER1" -or "USER2" -or "USER3"}
是数据类型 ScriptBlock。
PS C:\> ({"USER1" -or "USER2" -or "USER3"}).GetType().FullName
System.Management.Automation.ScriptBlock
我相信 PowerShell 会将其转换为字符串,但即使将其转换为字符串,它仍然不会被评估为布尔表达式:
PS C:> ({"USER1" -or "USER2" -or "USER3"}).ToString()
"USER1" -or "USER2" -or "USER3"
这将评估为 True 除非用户字面意思是“"USER1" - 或 "USER2" - 或 "USER3"”
如果您将其更改为括号表达式而不是脚本块:
where {$_.user.tostring() -ne ("USER1" -or "USER2" -or "USER3")}
那么它永远是真的。 ("USER1" -or "USER2" -or "USER3")
是布尔类型,其值始终为真。
PS C:\> ("USER1" -or "USER2" -or "USER3")
True
所以你基本上是 运行:
where {$_.user.tostring() -ne $true }
同样,即使 PowerShell 像我认为的那样将所有内容都转换为字符串,您也不太可能拥有名为 "True" 的用户。所以这永远是真的。
假设你处理一个数组,它可以用你写的类似的方式完成,甚至更短检查这个:
PS Z:\> @("food","drink","cheese","dog") -match "(food|cheese)"
food
cheese
PS Z:\> @("food","drink","cheese","dog") -notmatch "(food|cheese)"
drink
dog
where clause:
PS Z:\> @("food","drink","cheese","dog") | where {$_ -notmatch "(food|cheese)"}
drink
dog
有没有办法在 where 语句中组合多个逻辑运算符的参数?
基本上我有这样的说法:
<command chain> | where {$_.user.tostring() -ne "USER1" -and $_.user.tostring() -ne "USER2" -and $_.user.tostring() -ne "USER3"}
其实是一个比较长的链,所以我想把它简化成这样:
<command chain> | where {$_.user.tostring() -ne {"USER1" -or "USER2" -or "USER3"}}
以上说法不成立,请问有什么建议吗?
您想使用这个:
where {$_.user.tostring() -notin ("USER1","USER2","USER3")}
或者这个:
where {($_.user.tostring() -ne "USER1") -and ($_.user.tostring() -ne "USER2") -and ($_.user.tostring() -ne "USER3") }
这真的很简单。通常,布尔运算符应该只用于组合比较运算符(或您知道的其他表示布尔值的东西)。
您的代码:
where {$_.user.tostring() -ne {"USER1" -or "USER2" -or "USER3"}}
这根本就是废话。它总是会评估为真。 {"USER1" -or "USER2" -or "USER3"}
是数据类型 ScriptBlock。
PS C:\> ({"USER1" -or "USER2" -or "USER3"}).GetType().FullName
System.Management.Automation.ScriptBlock
我相信 PowerShell 会将其转换为字符串,但即使将其转换为字符串,它仍然不会被评估为布尔表达式:
PS C:> ({"USER1" -or "USER2" -or "USER3"}).ToString()
"USER1" -or "USER2" -or "USER3"
这将评估为 True 除非用户字面意思是“"USER1" - 或 "USER2" - 或 "USER3"”
如果您将其更改为括号表达式而不是脚本块:
where {$_.user.tostring() -ne ("USER1" -or "USER2" -or "USER3")}
那么它永远是真的。 ("USER1" -or "USER2" -or "USER3")
是布尔类型,其值始终为真。
PS C:\> ("USER1" -or "USER2" -or "USER3")
True
所以你基本上是 运行:
where {$_.user.tostring() -ne $true }
同样,即使 PowerShell 像我认为的那样将所有内容都转换为字符串,您也不太可能拥有名为 "True" 的用户。所以这永远是真的。
假设你处理一个数组,它可以用你写的类似的方式完成,甚至更短检查这个:
PS Z:\> @("food","drink","cheese","dog") -match "(food|cheese)"
food
cheese
PS Z:\> @("food","drink","cheese","dog") -notmatch "(food|cheese)"
drink
dog
where clause:
PS Z:\> @("food","drink","cheese","dog") | where {$_ -notmatch "(food|cheese)"}
drink
dog