如何使用 Where-Object/Wildcards 匹配多个字符串?

Posted

技术标签:

【中文标题】如何使用 Where-Object/Wildcards 匹配多个字符串?【英文标题】:How to match multiple strings with Where-Object/Wildcards? 【发布时间】:2022-01-04 23:37:44 【问题描述】:

我被要求使用Get-Command 提取命令,其中动词是getsetconvertTo 之一,名词以CXV 中的任何一个开头.

这是我目前所拥有的:

Get-Command | ?$_ -like "set[-][CXV]*" #Prints all commands that start with Set

我正在努力搜索setgetConvertTo 的多个动词。我尝试了几种不同的方法,但都无济于事。

【问题讨论】:

您可以通过使用-and-or 链接条件来继续表达式。 【参考方案1】:

我会这样做...使用 Get-Command 内置参数 = -Verb

代码的作用...

创建要匹配的动词列表 创建一个正则表达式 char-at-start-of-string 列表模式 抓取具有所需动词的命令 过滤带有以所需字符开头的名词的命令 将生成的命令按Verb 排序,然后按Noun

代码...

$VerbList = @(
    'get'
    'set'
    'convertto'
    )

$Regex_NounStartsWith = '^[cxv]'

Get-Command -Verb $VerbList |
    Where-Object 
        $_.Noun -match $Regex_NounStartsWith
         |
    Sort-Object -Property Verb, Noun

截断结果...

CommandType     Name                                               Version    Source                                                                                      
-----------     ----                                               -------    ------                                                                                      
Cmdlet          ConvertTo-Csv                                      3.1.0.0    Microsoft.PowerShell.Utility                                                                
Cmdlet          ConvertTo-Xml                                      3.1.0.0    Microsoft.PowerShell.Utility                                                                
Function        Get-CallerPreference                               5.31.0     PSLog                                                                                       
Function        Get-CallerPreference                               5.22.0     PSLog                                                                                       
Cmdlet          Get-Certificate                                    1.0.0.0    PKI                                                                                         
Cmdlet          Get-CertificateAutoEnrollmentPolicy                1.0.0.0    PKI                                                                                         
Cmdlet          Get-CertificateEnrollmentPolicyServer              1.0.0.0    PKI                                                                                         
Cmdlet          Get-CertificateNotificationTask                    1.0.0.0    PKI                                                                                         
Cmdlet          Get-ChildItem                                      3.1.0.0    Microsoft.PowerShell.Management                                                              
[*...snip...*]     

【讨论】:

这不是太复杂吗? @Suraj - 对我来说,这很简单。 对我来说,你的更复杂。另外,我的不使用别名,在适用的情况下使用内置参数而不是正则表达式,并且易于查看/阅读/理解。 [咧嘴]【参考方案2】:

您的开始是正确的,但是,-like 允许您仅匹配通配符模式,而 -match 允许您匹配正则表达式模式,您的正则表达式只需要稍作调整:

Get-Command | ?$_ -match "((^set)|(^get)|(^convertto))-[CXV]+"

这可以进一步缩短为:

Get-Command | ?$_ -match "((^[sg]et)|(^convertto))-[CXV]+"

如果您想要命令的排序输出:

Get-Command | ?$_ -match "((^[sg]et)|(^convertto))-[CXV]+" | Sort

参考:About Comparison Operators

【讨论】:

【参考方案3】:

Get-Command-Name参数接受wildcard expressions,可以直接按名词部分的第一个字符过滤:-Name *-[CXV]*

虽然您可以直接将-Name-Verb 参数(在Lee Dailey's helpful answer 中显示)结合使用,但您可以通过.Verb 执行后过滤属性 Get-Command 输出的 [System.Management.Automation.CommandInfo] 实例中的 em> 个:

Get-Command -Name *-[CXV]* | Where-Object Verb -in Get, Set, ConvertTo

另一个选项,使用单个 Where-Object 脚本块完全避免模式匹配($_.Noun[0] 返回名词部分的第一个字符):

Get-Command | 
  Where-Object  
    $_.Noun[0] -in 'C', 'X', 'V' -and $_.Verb -in 'Get', 'Set', 'ConvertTo'
  

另一种选择是使用regular expression,如Suraj's helpful answer 所示 - 尽管使用上面的通配符/面向对象的解决方案可以避免其增加的复杂性。


至于你尝试了什么

$_ -like "set[-][CXV]*"

通配符表达式不够复杂,无法匹配给定的一组子字符串(只有一组单个字符 可以匹配,例如 [CXV] 在您的尝试中)。

解决方案是要么只匹配*-[CXV]* 以过滤名词部分,并为动词部分添加与-and附加比较(如$_.Verb -in 'Get', 'Set', 'ConvertTo',如上所示) , 或改为使用 正则表达式,如 Suraj 的回答所示。

【讨论】:

以上是关于如何使用 Where-Object/Wildcards 匹配多个字符串?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用本机反应创建登录以及如何验证会话

如何在自动布局中使用约束标识符以及如何使用标识符更改约束? [迅速]

如何使用 AngularJS 的 ng-model 创建一个数组以及如何使用 jquery 提交?

如何使用laravel保存所有行数据每个行名或相等

如何使用 Math.Net 连接矩阵。如何使用 Math.Net 调用特定的行或列?

WSARecv 如何使用 lpOverlapped?如何手动发出事件信号?