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"
等效的,使用带有正则表达式 (regex) 转义序列的 PowerShell 字符串文字(RHS-split
是一个正则表达式):
"abc`r`ndef" -split '\r?\n' | Select-String -Pattern "abc"
有点不幸的是,Select-String
文档谈到对文本行进行操作,因为真正的操作单元是输入对象——正如我们所见,输入对象本身可能包含多行。
据推测,这来自通过 cmdlet 提供输入对象的典型用例,该Get-Content
cmdlet 会逐行输出文本文件的行。
请注意,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
如果您确实想逐行搜索默认输出格式,请使用以下成语:
... | Out-String -Stream | Select-String ...
但是,请注意,对于非字符串输入,后续处理通过使用条件查询属性Where-Object
来过滤输入更加健壮和可取。
也就是说,有充分的理由Select-String
需要隐式应用Out-String -Stream
字符串化,如本 GitHub 功能请求中所述。
[2] 更准确地说,.psobject.ToString()
按原样调用,或者 - 如果对象的ToString
方法支持IFormatProvider
-typed 参数 -.psobject.ToString([cultureinfo]::InvariantCulture)
以获得文化不变的表示 - 请参阅此答案以获取更多信息。