Powershell 中 Select-String 方法的“行”由什么构成?

Shu*_*eng 7 powershell split select-string

我希望在 Powershell中Select-String考虑\r\n(回车+换行)一行的结尾。

但是,如下所示,abc匹配整个整个输入:

PS C:\Tools\hashcat> "abc`r`ndef" | Select-String -Pattern "abc"

abc
def
Run Code Online (Sandbox Code Playgroud)

如果我将字符串分成两部分,则Select-String表现如我所料:

PS C:\Tools\hashcat> "abc", "def" | Select-String -Pattern "abc"

abc
Run Code Online (Sandbox Code Playgroud)

我怎样才能给出Select-String一个以 结尾的字符串\r\n,然后让这个 cmdlet 只返回那些包含匹配的字符串?

mkl*_*nt0 7

  • Select-String对每个(按需字符串化[1])输入对象进行操作。

  • 阿多行字符串,如"abc`r`ndef"为单个输入对象。

    • 相比之下,"abc", "def"是一个包含两个元素的字符串数组,作为两个输入对象传递。
  • 为了确保线的多线串的传递个别地,分割字符串转换成线的阵列使用Powershell的-split运算符:"abc`r`ndef" -split "`r?`n"

    • (?使`r可选的,以便也正确处理`n-only(LF-only,Unix-style)行尾。)

简而言之:

"abc`r`ndef" -split "`r?`n" | Select-String -Pattern "abc"
Run Code Online (Sandbox Code Playgroud)

等效的,使用带有正则表达式 (regex) 转义序列的 PowerShell 字符串文字(的 RHS-split是正则表达式):

"abc`r`ndef" -split '\r?\n' | Select-String -Pattern "abc"
Run Code Online (Sandbox Code Playgroud)

考虑到真正的操作单元是输入对象——如我们所见,输入对象本身可能包含多行,因此Select-String文档讨论了对文本行的操作有点不幸。 据推测,这来自于典型经由提供输入对象的情况下使用小命令,它输出一个文本文件的行逐个。
Get-Content

请注意,Select-String它不会直接返回匹配的字符串,而是将它们包装在[Microsoft.PowerShell.Commands.MatchInfo]包含有关匹配的有用元数据的对象中。然而,即使在那里也存在行比喻,因为它是.Line包含匹配字符串的属性。


[1] 可选阅读:如何Select-String字符串化输入对象

如果输入对象还不是字符串,则会将其转换为字符串,但可能不是您期望的方式:

宽泛地说,该.ToString()方法被称为每个非字符串输入对象上[2] ,其中对于非字符串是不一样的,你使用PowerShell的取得表示默认的输出格式(后者是你所看到的,当你打印对象所述控制台或使用Out-File,例如); 相反,它是你与得到相同的表示串内插在双引号字符串(当嵌入的可变参考或命令"...",例如,"$HOME"或"$(Get-Date)")。

通常,.ToString()只生成对象类型的名称,不包含任何特定于实例的信息;例如,$PSVersionTable字符串化为System.Management.Automation.PSVersionHashTable。

# Matches NOTHING, because Select-String sees
# 'System.Management.Automation.PSVersionHashTable' as its input.
$PSVersionTable | Select-String PSVersion 
Run Code Online (Sandbox Code Playgroud)

如果您确实想逐行搜索默认输出格式,请使用以下习惯用法:

... | Out-String -Stream | Select-String ...
Run Code Online (Sandbox Code Playgroud)

但是,请注意,对于非字符串输入,通过查询具有Where-Object条件的属性来过滤输入,对于后续处理来说更健壮且更可取。

也就是说,有一个强有力的理由Select-String需要隐式应用Out-String -Stream字符串化,如此 GitHub 功能请求 中所述。


[2] 更准确地说,.psobject.ToString()按原样调用,或者 - 如果对象的ToString方法支持IFormatProvider-typed 参数 -.psobject.ToString([cultureinfo]::InvariantCulture)以获得文化不变的表示 -有关更多信息,请参阅此答案。