列出与模式匹配的文件夹中的文件名,不包括文件内容
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 选项。
我正在使用以下递归列出包含 $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 选项。