我正在使用以下内容递归列出包含$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:Users 10MDocumentsWindowsPowerShell -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 $_.文件名 }