[英]Using PowerShell sls (Select-String) vs grep vs findstr
Could someone clarify how sls (Select-String) works compared to grep and findstr?有人可以澄清与 grep 和 findstr 相比 sls (Select-String) 是如何工作的吗?
grep: grep <pattern> files.txt
grep:
grep <pattern> files.txt
sls: sls <pattern> files.txt
(default parameter position for sls is pattern then file) sls:
sls <pattern> files.txt
(sls的默认参数位置是pattern然后是文件)
grep examples: grep "search text" *.log
; grep 示例:
grep "search text" *.log
; cat *.log | grep "search text"
sls examples: sls "search text" *.log
; sls 示例:
sls "search text" *.log
; cat *.log | grep "search text"
As an aside, all PowerShell Cmdlets are case-insensitive, unlike Linux tools which are generally always case-sensitive but also older tools like findstr which are case sensitive too, but findstr can be used in PowerShell, and works in situations where sls does not, for example: Get-Service | findstr "Sec"
顺便说一句,所有 PowerShell Cmdlet 都不区分大小写,不像 Linux 工具通常总是区分大小写,但也有像 findstr 这样的旧工具也区分大小写,但是 findstr 可以在 PowerShell 中使用,并且可以在 sls 不区分大小写的情况下工作,例如:
Get-Service | findstr "Sec"
Get-Service | findstr "Sec"
(this works without a problem!), but when we try to use sls in a similar way Get-Service | sls "Sec"
Get-Service | findstr "Sec"
(这没有问题!),但是当我们尝试以类似的方式使用 sls 时Get-Service | sls "Sec"
Get-Service | sls "Sec"
we get nothing (presumably this fails because sls works with strings, but Get-Service returns an object, so that's understandable - but what is findstr doing then in that it can see the output as a string?). Get-Service | sls "Sec"
我们什么也没得到(大概这会失败,因为 sls 处理字符串,但 Get-Service 返回一个对象,所以这是可以理解的 - 但是 findstr 做什么因为它可以将输出视为字符串?)。
So, my thinking is "ok, I need to make the output from Get-Service into a string to work with PowerShell Cmdlets", but that doesn't work (or not in a way that I would expect):因此,我的想法是“好的,我需要将 Get-Service 的输出转换为字符串以与 PowerShell Cmdlets 一起使用”,但这不起作用(或者不是我期望的方式):
Get-Service | Out-String | sls "Sec"
Get-Service | Out-String | sls "Sec"
(gives results, but odd) Get-Service | Out-String | sls "Sec"
(给出结果,但很奇怪)
(Get-Service).ToString() | sls "Sec"
(Get-Service).ToString() | sls "Sec"
(.ToString() just returns "System.Object[]") (Get-Service).ToString() | sls "Sec"
(.ToString() 只返回 "System.Object[]")
How in general should I turn an object into a string so that it can manipulate the information (in the same way that Get-Service | findstr "Sec"
can do so easily)?一般来说,我应该如何将对象转换为字符串,以便它可以操作信息(就像
Get-Service | findstr "Sec"
可以轻松做到的那样)?
Would appreciate if someone could clarify how things fit together in the above so that I can make more use of sls.如果有人能澄清上面的内容如何组合在一起,以便我可以更多地使用 sls,我将不胜感激。 In particular,
Get-Service | Out-String | sls "Sec"
特别是,
Get-Service | Out-String | sls "Sec"
Get-Service | Out-String | sls "Sec"
Get-Service | Out-String | sls "Sec"
does return stuff, just not the stuff I was expecting (is it searching for each character of "s" and "e" and "c" so is returning lots - that would not be very intuitive if so in my opinion)? Get-Service | Out-String | sls "Sec"
确实返回了东西,只是不是我期望的东西(它是否正在搜索“s”和“e”和“c”的每个字符,所以返回很多 - 如果在我看来这不是很直观)?
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.默认情况下,当您使用
Out-String
,它将管道输入对象(在本例中为服务对象数组)转换为单个字符串。 Luckily, the -Stream
switch allows each line to be output as a single string instead.幸运的是,
-Stream
开关允许将每一行作为单个字符串输出。 Regarding case-sensitivity, Select-String
supports the -CaseSensitive
switch.关于区分大小写,
Select-String
支持-CaseSensitive
开关。
# 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.无论哪种情况,
Select-String
使用正则表达式(使用-SimpleMatch
开关进行字符串匹配)对每个输入字符串进行模式匹配,并输出与该模式匹配的整个字符串。 So if you only pipe into it a single string with many lines, then all lines will be returned on a successful match.因此,如果您只将一个包含多行的字符串插入其中,那么在成功匹配时将返回所有行。
To complement AdminOfThings' helpful answer :为了补充AdminOfThings 的有用答案:
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] .为了在非字符串输入对象的显示字符串表示的行中找到字符串,因为它们会打印到控制台,您确实必须通过管道传输到
Out-String -Stream
,而默认情况下,简单的.ToString()
字符串化应用[1] 。
Select-String
should do it implicitly , as suggested in GitHub issue #10726 .Select-String
应该隐式执行此操作,如GitHub 问题 #10726 中所述。 Curiously, when piping to external programs such as findstr.exe
, PowerShell already does apply Out-String -Stream
implicitly ;奇怪的是,管道外部程序如当
findstr.exe
,PowerShell中已经不适用Out-String -Stream
含蓄; eg:例如:
Get-Date 1/1/2019 | findstr January
Get-Date 1/1/2019 | findstr January
works (in en
-based cultures), because it is implicitly the same as Get-Date 1/1/2019 | findstr January
有效(在基于en
的文化中),因为它与Get-Date 1/1/2019 | Out-String -Stream | findstr January
Get-Date 1/1/2019 | Select-String January
Get-Date 1/1/2019 | Select-String January
Get-Date 1/1/2019 | Select-String January
is the equivalent of Get-Date 1/1/2019 | Select-String January
相当于(Get-Date 1/1/2019).ToString([cultureinfo]::InvariantCulture) | Select-String January
(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
. (Get-Date 1/1/2019).ToString([cultureinfo]::InvariantCulture) | Select-String January
,因此不能正常工作,因为输入的计算结果为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. [1] 更准确地说,
.psobject.ToString()
被调用,或者按原样调用,或者 - 如果对象的ToString
方法支持IFormatProvider
类型的参数 - .psobject.ToString([cultureinfo]::InvariantCulture)
以便获得文化不变的表示 - 有关更多信息,请参阅此答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.