'Remove the at symbol ( @ ) and curly bracket ( { ) from Select-Sring output in Powershell
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
Solution 1:[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.
(...).Nameuses member-access enumeration to extract allNameproperty values from the file-info objects returned byGet-ChildItem.-match, the regular-expression matching operator, due to operating on an array of values, returns the sub-array of matching values.
To make your original command work:
Get-ChildItem | select -ExpandProperty Name |
Select-String -Pattern "1" | select -ExpandProperty Line
select -ExpandProperty Namemakesselect(Select-Object) return only theNameproperty values; by default (implied-Propertyparameter), a custom object that has aNameproperty is returned.select -ExpandProperty linesimilarly extracts theLineproperty value from theMicrosoft.PowerShell.Commands.MatchInfoinstances thatSelect-Stringoutputs.- Note that in PowerShell [Core] v7+ you could omit this step by instead using
Select-String's (new)-Rawswitch to request string-only output.
- Note that in PowerShell [Core] v7+ you could omit this step by instead using
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; changingSelect-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.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
