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.*; see Get-Help about_Regular_Expressions),

  • whereas Get-ChildItem -Filter/-Include accepts a wildcard expression (e.g., *sample*; see Get-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