1

I'm parsing filenames in Powershell, and when I use Get-ChildItem | select name, I get a clean output of the files:

file1.txt file2.txt file3.txt

But when I try to narrow down those files with Select-String, I'm getting a weird @ and { in front of my output:

Get-ChildItem | select name | Select-String -Pattern "1"

@{file1.txt}

Is there a parameter I'm missing? If I pipe with findstr rather than Select-String it works like a charm:

Get-ChildItem | select name | Findstr "1"

file1.txt

puterguy01
  • 135
  • 1
  • 10

1 Answers1

1

You can simplify and speed up your command as follows:

@((Get-ChildItem).Name) -match '1'

Note: @(), the array-subexpression operator, is needed to ensure that -match operates on an array, even if only one file happens to exist in the current dir.


To make your original command work:

Get-ChildItem | select -ExpandProperty Name | 
  Select-String -Pattern "1" | select -ExpandProperty Line
  • select -ExpandProperty Name makes select (Select-Object) return only the Name property values; by default (implied -Property parameter), a custom object that has a Name property is returned.

  • select -ExpandProperty line similarly extracts the Line property value from the Microsoft.PowerShell.Commands.MatchInfo instances that Select-String outputs.

    • Note that in PowerShell [Core] v7+ you could omit this step by instead using Select-String's (new) -Raw switch to request string-only output.

As for what you tried:

As stated, by not using -ExpandProperty, select name (implied -Property parameter) created a custom object ([pscustomobject] instance) with a Name property.

Select-String stringifies its input objects, if necessary, so it can perform a string search on them, which results in the representation you saw; here's a simulation:

# Stringify a custom object via an expandable string ("...")
PS> "$([pscustomobject] @{ Name = 'file1.txt' })"
@{Name=file1.txt}

As an aside:

  • The above stringification method is essentially like calling .ToString() on the input objects[1], which often results in useless string representations (by default, just the type name); a more useful and intuitive stringification would be to use PowerShell's rich output-formatting system, i.e. to use the string representation you would see in the console; changing Select-String's behavior to do that is the subject of this feature request on GitHub.

[1] Calling .ToString() directly on a [pscustomobject] instance is actually still broken as of PowerShell Core 7.0.0-rc.2, due to this bug; the workaround is to call .psobject.ToString() or to use an expandable string, as shown above.

mklement0
  • 382,024
  • 64
  • 607
  • 775