List file names in a folder matching a pattern, excluding file content
To complement Matt's helpful answer:
Specifically, because what you're piping to Select-String
are [System.IO.FileInfo]
objects - which is what Get-ChildItem
outputs - rather than strings, it is the contents of the files represented by these objects is being searched.
Assuming that you need to match only the file name part of each file's path and that your pattern can be expressed as a wildcard expression, you do not need Select-String
at all and can instead use Get-ChildItem
with -Filter
, as in Matt's answer, or the slower, but slightly more powerful -Include
.
Caveat:
Select-String -Pattern
accepts a regular expression (e.g.,.*sample.*
; seeGet-Help about_Regular_Expressions
),whereas
Get-ChildItem -Filter/-Include
accepts a wildcard expression (e.g.,*sample*
; seeGet-Help about_Wildcards
) - they are different things.
On a side note: If your intent is to match files only, you can tell Get-ChildItem
to restrict output to files (as opposed to potentially also directories) using -File
(analogously, you can limit output to directories with -Directory
).
Group-Object path
(group path
) will not work as intended, because the .Path
property of the match-information objects output by Select-String
contains the full filename, so you'd be putting each file in its own group - essentially, a no-op.
When using just Get-ChildItem
, the equivalent property name would be .FullName
, but what you're looking for is to group by parent path (the containing directory's path), .DirectoryName
), I presume, therefore:
... | Group-Object DirectoryName | Select-Object Name
This outputs the full path of each directory that contains at least 1 file with a matching file name.
(Note that the Name
in Select-Object Name
refers to the .Name
property of the group objects returned by Group-Object
, which in this case is the value of the .DirectoryName
property on the input objects.)
get-ChildItem $targetDir -recurse | where {$_.name -like $pattern} | select name
I went through the answer by @Itchydon
but couldn't follow the use of '-like' $pattern.
I was trying to list files having 32characters(letters and numbers) in the filename.
PS C:> Get-ChildItem C:\Users\ -Recurse | where {$_.name -match "[a-zA-Z0-9]{32}"} | select name
or
PS C:> Get-ChildItem C:\Users\010M\Documents\WindowsPowerShell -Recurse | Where-Object {$_.name -match "[A-Z0-9]{32}"} | select name
So, in this case it doesn't matter whether you use where or where-object.
Select-String
is doing what you told it to. Emphasis mine.
The Select-String cmdlet searches for text and text patterns in input strings and files.
So if you are just looking to match with file names just use -Filter
of Get-ChildItem
or post process with Where-Object
Get-ChildItem -Path $path -Recurse -Filter "*sample*"
That should return all files and folders that have sample in their name. If you just wanted files or directories you would be able to use the switches -File
or -Directory
to return those specific object types.
If your pattern is more complicated than a simple word then you might need to use Where-Object
like in Itchydon's answer with something like -match
giving you access to regex.
The grouping logic in your code should be redundant since you are returning single files that all have unique paths. Therefore I have not included that here. If you just want the paths then you can pipe into Select-Object -Expand FullName
or just (Get-ChildItem -Path $path -Recurse -Filter "*sample*").Fullname