在文件中搜索 RegEx 字符串并仅返回文件名、路径和字符串

Posted

技术标签:

【中文标题】在文件中搜索 RegEx 字符串并仅返回文件名、路径和字符串【英文标题】:Search for RegEx string in files and return ONLY file name, path and string 【发布时间】:2019-01-28 03:18:31 【问题描述】:

我有点坚持搜索正则表达式字符串。场景如下:

我有一堆具有特定扩展名 (*.tlt) 且内容随机的文件 所有文件都位于驱动器 F 上 BETA 文件夹的子文件夹中: 每个文件的内容中至少有一个Revision 1.234。 (有时多次 - 只有第一次出现很重要)

这是我目前所拥有的:

$files = gci f:\beta\ -Include "*.tlt" -Recurse
$results = $files |
           Select-String -Pattern 'Revision:.+.1[.]\d1,3'|
           ForEach-Object  $_.Matches  |
           select Value |
           Format-Table -GroupBy Filename

我需要的是一个 PowerShell 脚本,它可以搜索文件并返回带有完整路径的文件列表,并且只有修订版 1.234 而不是整行。

【问题讨论】:

嗯,你目前只选择value,所以你不能按Filename分组。此外,如果您要存储结果,则不应通过管道发送到 Format-Table。存储结果,如果需要,稍后使用Format-Table 显示它们。如果您只是将它用于分组,请改用Group-Object 请允许我给你一个标准的建议给新手:如果一个答案解决了你的问题,请点击它旁边的大复选标记 (✓) 接受它,也可以选择给它投票(up - 投票需要 15 个或更多声望点)。如果您发现其他答案有帮助,请给他们投票。接受(您将获得 2 个声望点)和投票可以帮助未来的读者。请参阅the relevant help-center article。如果您的问题尚未得到完全解答,请提供反馈或self-answer。 感谢您的建议。我现在已经标记它并为两者投票。 【参考方案1】:

在calculated properties 的帮助下可以实现单管道解决方案:

Get-ChildItem f:\beta -Filter *.tlt -Recurse | 
  Select-String -List -Pattern 'Revision:.+?\.\d3' |
    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 过滤(让文件系统提供者 进行过滤)而不是先收集所有文件信息对象,然后让 PowerShell 进行过滤。

Select-String -List 将每个输入文件中的匹配限制为第一个匹配。

Select-String 输出的每个匹配项都是一个 [Microsoft.PowerShell.Commands.MatchInfo] 实例,其中包含有关每个匹配项的丰富元数据,例如带有完整输入文件名的 .Path 和带有正则表达式 ( -Pattern) 匹配 - 此元数据用于填充由 Select-Object 通过上述计算属性创建的输出自定义对象。

【讨论】:

【参考方案2】:

您已经很接近了,但您不可避免地需要遍历您的文件。注意 -Filter-Include 快得多,因为它不会在过滤之前收集每个对象。

$fileList = Get-ChildItem -Path F:\beta -Filter *.tlt -Recurse
$results = foreach ($file in $fileList)

    $find = $file | Select-String -Pattern '(Revision:.+?\.\d1,3)'
    if ($find)
    
        @
            Path = $file.FullName
            Rev  = $find.Matches.Groups[0].Value
        
    

【讨论】:

以上是关于在文件中搜索 RegEx 字符串并仅返回文件名、路径和字符串的主要内容,如果未能解决你的问题,请参考以下文章

Bash:如何使用Regex搜索文件中的字符串并获取相关值

Python Pandas Regex:在列中搜索带有通配符的字符串并返回匹配项[重复]

REGEX - 如何在文件名中找到两个连字符?

C# - RegEx - 获取两行之间的字符串

在 python 中使用 mechanize 剥离 html 标签并仅返回文本

使用 Linq 和 Regex 比较 2 个字符串数组以进行部分匹配