首页 > 解决方案 > 如何在 Powershell 中检查两个字符串中的任何一个

问题描述

我们的应用程序使用以下命令来查找 IP 地址:

powershell -ExecutionPolicy Bypass "Get-NetIPAddress -AddressFamily IPv4 | Where-object -Property InterfaceAlias -eq "Wi-Fi"  | Where-object -Property AddressState -eq "Preferred" | Where-object -Property PrefixOrigin -eq "dhcp" | Select -ExpandProperty IPAddress"

我发现这在我的笔记本电脑上失败了,因为 Wifi 被称为“WiFi” - 如果我将命令更改为:

Where-object -Property InterfaceAlias -eq "Wi-Fi"

它工作正常。但是我如何检查其中任何一个?我不知道如何将命令更改为类似Where-object -Property InterfaceAlias (-eq "Wi-Fi" or -eq "WiFi")- 这不起作用。

标签: powershell

解决方案


正如评论中所建议的那样,切换到基于正则表达式的-matchoperator是最简单的解决方案:

Where-Object InterfaceAlias -match '^Wi-?Fi$' # matches both 'WiFi' and 'Wi-Fi'

注意需要使用anchors ^(字符串的开头)和$(字符串的结尾)来确保整个字符串匹配;默认情况下-match还会找到substrings。重复符号?表示前面的子表达式(-此处为字符)匹配0 次或 1次,表示匹配(如果存在),如果不匹配,则也匹配。

还:

  • 请注意,您的命令的引用被破坏了,并且只是意外起作用:通过不转义"字符。围绕(打算成为)嵌入 "的字符。(例如,在 中"Wi-Fi",它们在 PowerShell 看到它们之前被有效地删除;只是因为 PowerShell在参数解析模式下也接受不带引号的参数,您的命令仍然有效。

    • 虽然您可以使用\"转义嵌入的双引号,但更简单的方法是在这里完全省略它们,或者,如果从 PowerShell 的角度来看需要引用,则使用'(单引号) 进行嵌入引用。
  • Where-Object您可以使用单个脚本块 ( ) 将它们合并为一个,而不是使用 3 个单独的调用,{ ... }将条件与-and运算符连接起来;请注意,下面脚本块中的代码是在表达式模式下解析的,这确实需要引用文字字符串操作数。

  • 特别是因为您只期望一个... | Select-Object -ExpandProperty IPAddress返回值,所以用.替换更简单、更有效(...).IPAddress

  • 顺便说一句:在Windows PowerShell CLI中,当您按位置传递命令字符串时powershell.exe,该参数是隐含的;请注意,在PowerShell [Core] v6+ 的 CLI 中,默认值为 now ,因此您必须在那里使用。-Command-Filepwsh -ExecutionPolicy Bypass -Command "..."

powershell -ExecutionPolicy Bypass "(Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.InterfaceAlias -match '^Wi-?Fi$' -and $_.AddressState -eq 'Preferred' -and $_.PrefixOrigin -eq 'dhcp').IPAddress"

推荐阅读