简体   繁体   English

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

[英]How to match multiple strings with Where-Object/Wildcards?

I'm asked to extract commands using Get-Command , where the verb is one of get , set or convertTo and the noun starts with any of C , X or V .我被要求使用Get-Command提取命令,其中动词是getsetconvertTo之一,名词以CXV中的任何一个开头。

This is what I have so far:这是我到目前为止所拥有的:

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

I am struggling to search for multiple verbs that are either set , get , or ConvertTo .我正在努力搜索setgetConvertTo的多个动词。 I have attempted several different methods but to no avail.我尝试了几种不同的方法但无济于事。

here is how i would do it... using a Get-Command built in parameter = -Verb .这就是我将如何做到的......使用内置参数 = -VerbGet-Command

what the code does...代码的作用...

  • creates the list of verbs to match创建要匹配的动词列表
  • creates a regex char-at-start-of-string list pattern创建一个正则表达式 char-at-start-of-string 列表模式
  • grabs the commands that have the desired verbs抓取具有所需动词的命令
  • filters for the commands with nouns that start with the desired chars过滤带有以所需字符开头的名词的命令
  • sorts the resulting commands by Verb then by NounVerb排序结果命令,然后按Noun排序

the code...编码...

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

$Regex_NounStartsWith = '^[cxv]'

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

truncated results...截断的结果...

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...*]     

You started off correctly, however, -like lets you match only wildcard patterns whereas -match let you match regex patterns and your regex just needs a little tweaking:但是,您的开始是正确的, -match -like您匹配正则表达式模式,您的正则表达式只需要稍作调整:

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

This can be further shortened to:这可以进一步缩短为:

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

If you want a sorted output of the commands:如果你想要一个排序的 output 的命令:

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

Ref: About Comparison Operators参考: 关于比较运算符

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

Another option, with a single Where-Object script block that avoids pattern matching altogether ( $_.Noun[0] returns the noun part's first character):另一种选择,使用单个Where-Object脚本块来完全避免模式匹配( $_.Noun[0]返回名词部分的第一个字符):

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

Yet another option is to use a regular expression , as shown in Suraj's helpful answer - though its added complexity can be avoided with the wildcard / object-oriented solutions above.另一种选择是使用正则表达式,如Suraj 的有用答案所示 - 尽管可以通过上面的通配符/面向对象的解决方案避免其增加的复杂性。


As for what you tried :至于你尝试了什么:

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

Wildcard expressions aren't sophisticated enough to match one of a given set of substrings (only a set of individual characters can be matched, such [CXV] in your attempt).通配符表达式不够复杂,无法匹配给定的一组子字符串(只能匹配一组单独的字符,例如[CXV]在您的尝试中)。

The solution is to either match just against *-[CXV]* to filter the noun part and add an additional comparison with -and for the verb part (such as $_.Verb -in 'Get', 'Set', 'ConvertTo' , as shown above), or to use a regular expression instead, as shown in Suraj's answer.解决方案是仅匹配*-[CXV]*以过滤名词部分,并为动词部分添加与-and附加比较(例如$_.Verb -in 'Get', 'Set', 'ConvertTo' ,如上所示),或者改用正则表达式,如 Suraj 的回答所示。

So, the regex path is better.因此,正则表达式路径更好。 . . . . but to answer your actual question about wildcards, I'm going to have to share an answer that people are gonna just poop on.但要回答你关于通配符的实际问题,我将不得不分享一个人们只会大便的答案。 I will have to disagree with mklement0's assertion that this can't be done with wildcards (aka "-like" matching).我将不得不不同意mklement0 的断言,即这不能用通配符(又名“-like”匹配)来完成。

$matches="Get*","Set*","ConvertTo*"    # List of substrings to match
Get-Command | ? {foreach ($match in $matches) {if ($_ -ilike $match) {return $true}}}    # The actual matching

Note, I used "-ilike" because I decided to be case insensitive.请注意,我使用“-ilike”是因为我决定不区分大小写。

Here's more on PowerShell comparison operators: > Link <以下是关于 PowerShell 比较运算符的更多信息:> 链接<

Its not pretty, but you can store it in a list and match what you're looking to match.它不漂亮,但您可以将其存储在列表中并匹配您要匹配的内容。 I'm sure if you were looking through 6 trillion records for 4 million matches, this would be slow.我敢肯定,如果您要查看 400 万场比赛的 6 万亿条记录,这会很慢。 . . . . but since we're talking about scripting, it gets the job done.但既然我们在谈论脚本,它就可以完成工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM