简体   繁体   English

使用 PowerShell sls (Select-String) vs grep vs findstr

[英]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]

    • You shouldn't have to do this manually , however : 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
    • By contrast, 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM