我使用下面的递归列出包含$pattern
的文件夹中的所有文件
Get-ChildItem $targetDir -recurse | Select-String -pattern "$pattern" | group path | select name
但它似乎同时列出了名称和 content 中包含$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关键字/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
但不返回任何结果。
6条答案
按热度按时间hxzsmxv21#
Select-String
正在做您让它做事情重点是我Select-String cmdlet在输入字符串和文件中搜索文本和文本模式。
因此,如果您只是希望与文件名匹配,只需使用
Get-ChildItem
的-Filter
或使用Where-Object
进行后处理这将返回所有名称中包含sample的文件 * 和文件夹 *。如果您只需要文件或目录,则可以使用开关
-File
或-Directory
来返回这些特定的对象类型。如果你的模式比一个简单的单词更复杂,那么你可能需要使用
Where-Object
,就像在Itchydon's answer中一样,-match
让你访问regex。代码中的分组逻辑应该是冗余的,因为返回的是具有唯一路径的单个文件。因此,我没有在这里包括分组逻辑。如果只需要路径,则可以通过管道输入
Select-Object -Expand FullName
或(Get-ChildItem -Path $path -Recurse -Filter "*sample*").Fullname
m1m5dgzv2#
wfsdck303#
要 * 补充 * Matt's helpful answer:
具体来说,因为您传送到
Select-String
的是[System.IO.FileInfo]
对象-这是Get-ChildItem
输出的-而不是 * 字符串*,所以搜索的是这些对象所表示的文件的*内容。假设您只需要匹配每个文件路径的 file name 部分,并且您的模式可以表示为 * 通配符表达式 *,则您根本不需要
Select-String
,而是可以将Get-ChildItem
与-Filter
一起使用,如Matt的答案所示,或者使用速度较慢但功能稍强的-Include
。Select-String -Pattern
接受 * 正则表达式 *(例如,.*sample.*
;参见X1 M9 N1 X),Get-ChildItem -Filter/-Include
接受 * 通配符表达式 *(例如,*sample*
;参见Get-Help about_Wildcards
)-它们是 * 不同的东西 *。顺便说一句:如果您只想匹配 files,您可以使用
-File
告诉Get-ChildItem
将输出限制为文件(而不是也可能限制为 directories)(类似地,您可以使用-Directory
将输出限制为目录)。Group-Object path
(group path
)将无法正常工作,因为Select-String
输出的match-information对象的.Path
属性包含 * 完整的文件名 *,因此您需要将每个文件放在自己的组中-实际上是一个空操作。当只使用
Get-ChildItem
时,等效的属性名将是.FullName
,但您要查找的是按 parent path(包含目录的路径)分组,.DirectoryName
),因此我假定:这将输出每个 * 目录 * 的完整路径,该目录至少包含1个具有匹配文件名的文件。
(Note
Select-Object Name
中的Name
指的是Group-Object
所传回之 group 对象的.Name
属性,在这个范例中,它是输入对象上的.DirectoryName
属性值。)dphi5xsq4#
我通过@Itchydon查看了答案
但无法遵循“-like”$模式的使用。
我试图列出文件名中包含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都无关紧要。
eagi6jfj5#
为了补充@mklement0给出的完美答案,您可以要求Powershell通过追加管道符来打印完整路径,如下所示:
注意:在搜索文件夹时,可能会出现基于安全性的错误,因此我们使用SilentlyContinue选项。
ergxz8rk6#
您可以直接使用select-string来搜索与某个字符串匹配的文件,是的,这将返回filename:count:content... etc,但是,在内部,这些文件具有您可以选择或忽略的名称,您需要的是“filename”来执行此操作,并将其导入“select-object”,从输出中选择“FileName”。
因此,要选择所有具有“Subject:Web服务已重新启动”,您可以执行以下操作:
选择-字符串-路径..MSG -模式'主题:Web服务已重新启动' -列表|选择对象文件名
此外,要动态删除这些文件,可以使用RM命令插入ForEach语句,如下所示:
选择-字符串-路径..MSG -模式'主题:Web服务已重新启动' -列表|选择对象文件名|foreach { rm $_.文件名}