[英]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
提取命令,其中动词是get
、 set
或convertTo
之一,名词以C
、 X
或V
中的任何一个开头。
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
.我正在努力搜索
set
、 get
或ConvertTo
的多个动词。 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
.这就是我将如何做到的......使用内置参数 =
-Verb
的Get-Command
。
what the code does...代码的作用...
Verb
then by Noun
Verb
排序结果命令,然后按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
's -Name
parameter accepts wildcard expressions , which allow you to directly filter by the first character of the noun part: -Name *-[CXV]*
Get-Command
的-Name
参数接受通配符表达式,允许您直接按名词部分的第一个字符进行过滤: -Name *-[CXV]*
While you can not directly combine -Name
with the -Verb
parameter that is shown in Lee Dailey's helpful answer , you can perform post-filtering via the .Verb
property of the [System.Management.Automation.CommandInfo]
instances that Get-Command
outputs:虽然您不能直接将
-Name
与Lee Dailey 的有用答案中显示的-Verb
参数结合起来,但您可以通过Get-Command
输出的[System.Management.Automation.CommandInfo]
实例的.Verb
属性执行后过滤:
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.