我有点不喜欢这个正则表达式字符串搜索。情况如下:
这是我到目前为止所拥有的:
$files = gci f:\beta\ -Include "*.tlt" -Recurse
$results = $files |
Select-String -Pattern 'Revision:.+.{1}[.]\d{1,3}'|
ForEach-Object { $_.Matches } |
select Value |
Format-Table -GroupBy Filename
我需要的是一个PowerShell脚本,该脚本可搜索文件并返回具有完整路径的文件列表,并且仅包含修订版1.234,而不是整行。
答案 0 :(得分:2)
您已经很接近了,但是您不可避免地需要遍历文件。注意-Filter
比-Include
快得多,因为它不会在过滤之前收集每个对象。
$fileList = Get-ChildItem -Path F:\beta -Filter *.tlt -Recurse
$results = foreach ($file in $fileList)
{
$find = $file | Select-String -Pattern '(Revision:.+?\.\d{1,3})'
if ($find)
{
@{
Path = $file.FullName
Rev = $find.Matches.Groups[0].Value
}
}
}
答案 1 :(得分:2)
借助calculated properties,可以实现单管道解决方案:
Get-ChildItem f:\beta -Filter *.tlt -Recurse |
Select-String -List -Pattern 'Revision:.+?\.\d{3}' |
Select-Object @{ n='FullName'; e='Path' }, @{ n='Revision'; e={ $_.Matches.Value } }
示例输出:
FullName Revision
-------- --------
/Users/jdoe/foo.tlt Revision: 1.234
/Users/jdoe/sub/bar.tlt Revision: 10.235
如TheIncorrigible1's answer中所述,使用-Filter
的效果比使用-Include
更好,因为-Filter
在源头过滤 (让文件系统 provider 进行过滤),而不是先收集所有文件信息对象,然后让 PowerShell 进行过滤。
Select-String -List
将每个输入文件中的匹配限制为 first 匹配。
Select-String
输出的每个匹配项都是一个[Microsoft.PowerShell.Commands.MatchInfo]
实例,其中包含有关每个匹配项的丰富元数据,例如.Path
和完整的输入文件名,以及{{1} }中包含有关正则表达式(.Matches
)匹配内容的信息-此元数据用于通过上述计算出的属性填充-Pattern
创建的输出自定义对象。