PowerShell全局模式匹配

6

我正在浏览 C:\ProgramFiles 中查找名为 log4j-core-x.y.z.jar 的 jar 文件。 我试图匹配最后一位数字 z,它可以是一个或两个数字(0-99)。 我似乎无法得到正确的glob模式来实现这一点。

代码:

PS C:\Users\Administrator> Get-ChildItem -Path 'C:\Program Files\' -Filter log4j-core-*.*.[1-9][0-9].jar -Recurse -ErrorAction SilentlyContinue -Force | %{$_.FullName}

这样做没有结果,但是当我使用所有通配符,比如 -Filter log4j-core-*.*.*.jar 时,会得到:
C:\Program Files\apache-log4j-2.16.0-bin\apache-log4j-2.16.0-bin\log4j-core-2.16.0-javadoc.jar
C:\Program Files\apache-log4j-2.16.0-bin\apache-log4j-2.16.0-bin\log4j-core-2.16.0-sources.jar
C:\Program Files\apache-log4j-2.16.0-bin\apache-log4j-2.16.0-bin\log4j-core-2.16.0-tests.jar
C:\Program Files\apache-log4j-2.16.0-bin\apache-log4j-2.16.0-bin\log4j-core-2.16.0.jar

我关心获得的唯一内容是 C:\Program Files\apache-log4j-2.16.0-bin\apache-log4j-2.16.0-bin\log4j-core-2.16.0.jarlog4j-core-2.16.0.jar

2个回答

5

-Filter不支持使用正则表达式字符范围, 如[A-Z][0-9]作为过滤器。感谢mklement0指出这一点。

根据Get-ChildItem官方文档中的参数描述:

过滤字符串传递给.NET API以枚举文件。该API仅支持*?通配符。

请尝试使用以下内容:

Get-ChildItem -Path 'C:\Program Files\' -Filter log4j-core-*.*.??.jar -Recurse -ErrorAction SilentlyContinue -Force |
Where-Object {
    $_.Name -match '\.\d{1,2}\.jar$'
    # => Ends with a . followed by 1 or 2 digits and the .jar extension
}

3

Santiago Squarzon的有用回答提供了一个基于正则表达式的解决方案,它具有比本例要求更复杂的匹配潜力。

让我补充一下你自己的尝试,提供一个基于通配符的解决方案:

  • -Filter参数不支持PowerShell的通配符语法;它只支持*?作为通配符元字符(如Santiago所述),而不支持字符范围/集合构造,例如[0-9]

    • 相反,-Filter参数由平台的文件系统API解释,在Windows上还有传统的怪癖 - 请参见此答案

    • 也就是说,对于-Filter支持的模式,其使用优于-Include(见下文),因为它在源头上进行过滤,性能更好。

  • 相比之下,-Include参数使用PowerShell的通配符,并且还支持多个模式。

与正则表达式不同,在PowerShell的通配符语言中,字符范围/集合表达式不支持重复(量词)逻辑,并且每个表达式匹配恰好一个字符(就像?对于任何单个字符一样;*是唯一一个隐式支持重复:零个或多个字符)。

因此,[1-9][0-9]精确匹配2个字符(数字),而只匹配一个数字([0-9])需要额外的模式:

Get-ChildItem -Recurse 'C:\Program Files' -Include log4j-core-*.*.[0-9].jar, log4j-core-*.*.[1-9][0-9].jar -ErrorAction SilentlyContinue -Force | 
  ForEach-Object FullName

注意事项:

  • 使用-Include(或-Exclude不带-Recurse无法按照预期工作 - 请参见此答案

  • 截至PowerShell 7.2,将-Recurse-Include组合使用会由于低效实现而导致性能问题 - 请参见GitHub问题#8662


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接