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



我正在使用以下内容递归列出包含$pattern的文件夹中的所有文件

Get-ChildItem $targetDir -recurse | Select-String -pattern "$pattern" | group path | select name

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

C:tmpconfig.include
C:tmpREADME.md
C:tmpspecsSAMPLE.data.nuspec
C:tmpspecsSAMPLE.Connection.nuspec

现在:

C:tmpconfig.include
C:tmpREADME.md

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

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

$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

但它不返回任何结果。

Select-String正在做你告诉它的事情。强调我的。

选择字符串 cmdlet 在输入字符串和文件中搜索文本和文本模式。

因此,如果您只是想与文件名匹配,只需使用Get-ChildItem-Filter或带有Where-Object的后期处理

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

这应该返回名称中包含示例的所有文件和文件夹。如果您只需要文件或目录,则可以使用开关-File-Directory返回这些特定的对象类型。

如果你的模式比一个简单的词更复杂,那么你可能需要使用Where-Object,比如在 Itchydon 的答案中,比如-match让你访问正则表达式。


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

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

补充Matt的有用答案:

具体来说,因为您要管道Select-String的是[System.IO.FileInfo]对象(这是Get-ChildItem输出的内容)而不是字符串,因此正在搜索的是这些对象所表示的文件的内容

假设您只需要匹配每个文件路径的文件名部分,并且您的模式可以表示为通配符表达式,您根本不需要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使用-File将输出限制为文件(而不是可能也是目录)(类似地,您可以将输出限制为带有-Directory目录)。


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

当只使用Get-ChildItem时,等效的属性名称将是.FullName,但您要查找的是按路径(包含目录的路径)分组,.DirectoryName),因此我认为:

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

这将输出每个目录的完整路径,该目录包含至少 1 个具有匹配文件名的文件。
(请注意,Select-Object Name中的Name是指Group-Object返回的对象的.Name属性,在本例中是输入对象上.DirectoryName属性的值。

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

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

注意:在搜索可能会根据安全性收到错误的文件夹时,因此我们使用"静默继续"选项。

我通过@Itchydon浏览了答案

但无法遵循"类似"$pattern的使用。

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

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

附言:>Get-ChildItem C:Users10MDocumentsWindowsPowerShell -Recurse | Where-Object {$_.name -match "[A-Z0-9]{32}"} | select name

因此,在这种情况下,无论您使用 where 还是where-object都没有关系

您可以直接使用select-string来搜索与某个字符串匹配的文件,是的,这将返回文件名:计数:内容...等等,但是,在内部,这些名称您可以选择或省略,您需要的是"文件名"来执行此操作,将其管道传输到"选择对象",从输出中选择"文件名"。

因此,要选择全部*。具有"主题: Web 服务重新启动"模式的 MSG 文件,您可以执行以下操作:

选择字符串路径 .*。味精模式"主题:Web 服务重新启动" -列表 |选择对象文件名

此外,要动态删除这些文件,您可以使用 RM 命令将 pip 到 ForEach 语句中,如下所示:

选择字符串路径 .*。味精模式"主题:Web 服务重新启动" -列表 |选择对象文件名 |foreach { rm $_.文件名 }

最新更新