列出与模式匹配的文件夹中的文件名,不包括文件内容

List file names in a folder matching a pattern, excluding file content

我正在使用以下递归列出包含 $pattern

的文件夹中的所有文件
Get-ChildItem $targetDir -recurse | Select-String -pattern "$pattern" | group path | select name

但它似乎都列出了名称中和 内容 中包含 $pattern 的文件,例如当我 运行 以上 $pattern="SAMPLE" 我得到:

C:\tmp\config.include
C:\tmp\README.md
C:\tmp\specs\SAMPLE.data.nuspec
C:\tmp\specs\SAMPLE.Connection.nuspec

现在:

C:\tmp\config.include
C:\tmp\README.md

确实包含 SAMPLE keywords/text 但我不关心这个,我只需要命令列出文件名而不是内容与模式匹配的文件。我错过了什么?

基于以下答案我也尝试过:

$targetDir="C:\tmp\"
Get-ChildItem $targetDir -recurse | where {$_.name -like "SAMPLE"} | group path | select name

和:

$targetDir="C:\tmp\"
Get-ChildItem $targetDir -recurse | where {$_.name -like "SAMPLE"} | select name

但它没有 return 任何结果。

get-ChildItem $targetDir -recurse | where {$_.name -like $pattern} | select name

Select-String 正在按照您的指示进行操作。强调我的。

The Select-String cmdlet searches for text and text patterns in input strings and files.

因此,如果您只是想匹配文件名,只需使用 -Filter of Get-ChildItem 或 post process with Where-Object

Get-ChildItem -Path $path -Recurse -Filter "*sample*"

那应该 return 所有文件 和文件夹 名称中包含样本。如果您只想要文件或目录,您可以使用开关 -File-Directory 到 return 那些特定的对象类型。

如果你的模式比一个简单的单词更复杂,那么你可能需要像 一样使用 Where-Object-match 这样的东西来让你访问正则表达式。


代码中的分组逻辑应该是多余的,因为您正在 returning 具有唯一路径的单个文件。因此我没有把它包括在这里。如果您只想要路径,那么您可以通过管道输入 Select-Object -Expand FullName(Get-ChildItem -Path $path -Recurse -Filter "*sample*").Fullname

补充 :

具体来说,因为 您要传输到 Select-String 的是 [System.IO.FileInfo] 对象 - 这就是 Get-ChildItem 输出 - 而不是 strings,搜索的是这些对象所代表的文件的 contents .

假设您只需要匹配每个文件路径的文件名部分,并且您的模式可以表示为通配符表达式,您根本不需要 Select-String,而是可以将 Get-ChildItem-Filter 一起使用,如 Matt 的回答,或者更慢但稍微更强大的 -Include

警告

  • Select-String -Pattern 接受 正则表达式 (例如,.*sample.*;参见 Get-Help about_Regular_Expressions),

  • Get-ChildItem -Filter/-Include 接受 通配符表达式 (例如,*sample*;参见 Get-Help about_Wildcards)- 它们是 不同的东西.

附带说明:如果您的目的是仅匹配 文件 ,您可以告诉 Get-ChildItem 限制输出到文件(而不是可能还 directories) 使用 -File(类似地,您可以使用 -Directory 限制输出到目录)。


Group-Object path (group path) 不会按预期工作,因为 Select-String 输出的匹配信息对象的 .Path 属性 包含完整文件名,因此您会将每个文件放在自己的组中 - 本质上是空操作。

当仅使用 Get-ChildItem 时,等效的 属性 名称将是 .FullName,但您要查找的是按 parent[=83] 分组=] 路径(包含目录的路径),.DirectoryName),我推测,因此:

... | Group-Object DirectoryName | Select-Object Name

这会输出每个 目录的完整路径 ,其中至少包含 1 个具有匹配文件名的文件。
(注意Select-Object Name中的Name指的是Group-Object返回的对象的.Name属性,在这种情况下,它是输入对象上 .DirectoryName 属性 的值。)

您可以直接使用 select-string 来搜索与特定字符串匹配的文件,是的,这将 return filename:count:content ... 等等,但是,在内部这些名称您可以选择或省略,您需要的是 "filename" 将此管道传输到 "select-object" 从输出中选择 "FileName"。

因此,对于 select 所有具有 "Subject: Webservices restarted" 格式的 *.MSG 文件,您可以执行以下操作:

Select-String -Path .*.MSG -Pattern 'Subject: WebServices Restarted' -List | select-object Filename

此外,要即时删除这些文件,您可以使用 RM 命令插入 ForEach 语句,如下所示:

Select-String -Path .*.MSG -Pattern 'Subject: WebServices Restarted' -List | select-object Filename | foreach { rm $_.FileName }

我自己试过了,100% 有效。

希望对您有所帮助

我看了@Itchydon 的回答

但无法遵循“-like”$pattern 的使用。

我试图列出文件名中包含 32 个字符(字母和数字)的文件。

PS C:> Get-ChildItem C:\Users\ -Recurse | where {$_.name -match "[a-zA-Z0-9]{32}"} | select name

PS C:> Get-ChildItem C:\Users0M\Documents\WindowsPowerShell -Recurse | Where-Object {$_.name -match "[A-Z0-9]{32}"} | select name

因此,在这种情况下,使用 where 还是 where-object.[=12= 并不重要]

为了补充@mklement0 的出色回答,您可以要求 Powershell 通过附加管道来打印完整路径,如下所示:

Get-ChildItem -Recurse -ErrorAction SilentlyContinue -Force -Filter "*sample*" | %{$_.FullName}

注意:搜索文件夹时,基于安全性可能会出错,因此我们使用 SilentlyContinue 选项。