比较powershell if语句中的多个通配符模式



如何比较if语句上的多个通配符模式?

if ($file.Name -like "*test*", "*.tmp")  
{
# do something
}

不幸的是,无论是-like(通配符匹配运算符)还是-match(正则表达式匹配运算符)都不支持模式数组从PowerShell 7.2.x开始:

  • 拥有这种能力(使用任何一个模式匹配被认为是整体匹配)将是有用的;GitHub issue #2132要求在未来的PowerShell (Core)版本中实现它。

  • 当你试图在RHS上使用数组时,PowerShell目前报告没有错误,它的当前行为实际上是无用的:数组是stringized形成一个单个字符串,这意味着它的元素与空格连接;即$file.Name -like "*test*", "*.tmp"$file.Name -like "*test* *.tmp"相同

然而,作为解决方案您可以使用-match单个regex模式,该模式使用替代(|)匹配多个值之一:

if ($file.Name -match 'test|.tmp$') {
# do something
} 

注意:

  • -match默认匹配子字符串,因此不需要与*通配符元字符等效的正则表达式。

    相反,如果您希望
    • 模式出现在某个位置,则需要锚定模式,例如使用上面的$来断言子表达式.tmp匹配字符串的结尾
  • 正则表达式比通配符强大得多,它有更多的元字符,可能需要用转义;在这种情况下,匹配任何字符的元字符.必须转义为.,以便匹配为文字.

    • 对于(sub)字符串的程序化转义要在正则表达式中逐字解释,使用[regex]::Escape(),例如[regex]::Escape('.tmp'),生成'.tmp'

如果您更喜欢使用-like,则需要两个操作,您必须与-or连接,如js2010在对问题的评论中所示:

if ($file.Name -like '*test*' -or $file.name -like '*.tmp') {
# do something
}

如果模式的数量很大或事先不知道,使用循环,例如通过[intrinsic.ForEach()方法](intrinsic.Where()方法):

$patterns = '*test*', '*.tmp'  # Array of patterns
if ($patterns.Where({ $file.Name -like $_ }, 'First')) {
# do something
}
最后,值得注意的是Get-ItemandGet-ChildItem支持-Include(和-Exclude)参数支持多个模式(不像-Filter),所以你可以预过滤你的文件,而不需要检查他们的名字;例如:
Get-Item .* -Include *test*, *.tmp

不幸的是,-Include-Exclude是出了名的挑剔,除了(大多数情况下)也使用-Recurse;例如,使用Get-ChildItem . -Include *test*, *.tmp按预期工作-详细信息请参阅此回答。

相关内容

  • 没有找到相关文章

最新更新