我使用以下内容递归列出包含$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关键字/文本,但我并不关心,我只需要命令列出文件名而不是文件,其内容与模式匹配。我错过了什么?
根据以下答案,我也尝试过:
$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
但它不会返回任何结果。
答案 0 :(得分:25)
Select-String
正在做你告诉它的事情。强调我的。
Select-String cmdlet在输入字符串和文件中搜索文本和文本模式。
因此,如果您只是想与文件名匹配,请使用-Filter
的{{1}}或使用Get-ChildItem
Where-Object
这应该返回名称中包含样本的所有文件和文件夹。如果您只是想要文件或目录,则可以使用开关Get-ChildItem -Path $path -Recurse -Filter "*sample*"
或-File
来返回这些特定对象类型。
如果您的模式比简单的单词更复杂,那么您可能需要像Itchydon's answer一样使用-Directory
Where-Object
之类的-match
,以便您访问正则表达式。
代码中的分组逻辑应该是冗余的,因为您返回的所有文件都具有唯一路径。因此我没有在这里包括。如果您只想要路径,那么您可以管道Select-Object -Expand FullName
或(Get-ChildItem -Path $path -Recurse -Filter "*sample*").Fullname
答案 1 :(得分:6)
具体来说,因为您Select-String
[System.IO.FileInfo]
对象的管道是什么 - Get-ChildItem
输出 - 而不是字符串 ,正在搜索这些对象所代表的文件的 内容 。
假设您只需要匹配每个文件路径的文件名部分,并且您的模式可以表示为通配符表达式,则不需要{{ 1}}然后可以使用Select-String
和Get-ChildItem
一起使用,就像马特的回答一样,或者更慢但更强大的-Filter
。
警告:
-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
输出的匹配信息对象的.Path
属性包含完整文件名< / em>,所以你要将每个文件放在它自己的组中 - 基本上是一个无操作。
仅使用Select-String
时,等效的属性名称为Get-ChildItem
,但您要查找的是按父路径分组(包含目录的路径) ,.FullName
),我猜,因此:
.DirectoryName
这将输出每个目录的完整路径,其中包含至少1个具有匹配文件名的文件。
(请注意... | Group-Object DirectoryName | Select-Object Name
中的Name
是指Select-Object Name
返回的组对象的.Name
属性,在这种情况下是值输入对象上的Group-Object
属性。)
答案 2 :(得分:3)
get-ChildItem $targetDir -recurse | where {$_.name -like $pattern} | select name
答案 3 :(得分:0)
您可以直接使用选择字符串来搜索与某个字符串匹配的文件,是的,这将返回filename:count:content ...等,但是,在内部,这些名称可以选择或忽略,一个您需要的是“文件名”来将其通过“选择对象”通过输出从中选择“文件名”。
因此,要选择所有具有“主题:Web服务重新启动”模式的* .MSG文件,您可以执行以下操作:
选择字符串-Path。*。MSG-模式'主题:WebServices重新启动' -列表|选择对象文件名
另外,要即时删除这些文件,您可以使用RM命令将Foreach语句插入如下:
选择字符串-Path。*。MSG-模式'主题:WebServices重新启动' -列表|选择对象文件名| foreach {rm $ _。FileName}
我自己尝试过,可以100%工作。
我希望这对您有帮助
答案 4 :(得分:0)
我通过@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:\Users\010M\Documents\WindowsPowerShell -Recurse | Where-Object {$_.name -match "[A-Z0-9]{32}"} | select name
因此,在这种情况下,无论使用 where 还是 where-object 。
答案 5 :(得分:0)
为了补充@mklement0 的出色回答,您可以通过添加管道来要求 Powershell 打印完整路径,如下所示:
Get-ChildItem -Recurse -ErrorAction SilentlyContinue -Force -Filter "*sample*" | %{$_.FullName}
注意:根据安全性搜索可能出错的文件夹时,我们使用 SilentlyContinue 选项。