Could someone clarify how sls (Select-String) works compared to grep and findstr?
grep: grep
sls: sls
To complement AdminOfThings' helpful answer:
In order to find strings among the lines of the for-display string representations of non-string input objects as they would print to the console you indeed have to pipe to Out-String -Stream
, whereas by default, simple .ToString()
stringification is applied[1].
Select-String
should do it implicitly, as suggested in this GitHub issue.Curiously, when piping to external programs such as findstr.exe
, PowerShell already does apply Out-String -Stream
implicitly; e.g:
Get-Date 1/1/2019 | findstr January
works (in en
-based cultures), because it is implicitly the same as Get-Date 1/1/2019 | Out-String -Stream | findstr January
Get-Date 1/1/2019 | Select-String January
is the equivalent of (Get-Date 1/1/2019).ToString([cultureinfo]::InvariantCulture) | Select-String January
, and therefore does not work, because the input evaluates to 01/01/2019 00:00:00
.[1] More accurately, .psobject.ToString()
is called, either as-is, or - if the object's ToString
method supports an IFormatProvider
-typed argument - as .psobject.ToString([cultureinfo]::InvariantCulture)
so as to obtain a culture-invariant representation - see this answer for more information.
When you use Out-String
by default, it turns the piped input object (an array of service objects in this case) into a single string. Luckily, the -Stream
switch allows each line to be output as a single string instead. Regarding case-sensitivity, Select-String
supports the -CaseSensitive
switch.
# For case-insensitive regex match
Get-Service | Out-String -Stream | Select-String "Sec"
# For case-sensitive regex match
Get-Service | Out-String -Stream | Select-String "Sec" -CaseSensitive
# For case-sensitive non-regex match
Get-Service | Out-String -Stream | Select-String "Sec" -CaseSensitive -SimpleMatch
In either case, Select-String
uses regex (use the -SimpleMatch
switch to do a string match) to pattern match against each input string and outputs the entire string that matched the pattern. So if you only pipe into it a single string with many lines, then all lines will be returned on a successful match.