如何使用换行符在 PowerShell 的 Write-Output 中获取实际的单独行

How to get actual separate lines in PowerShell's Write-Output using a newline character

我尝试创建一个多行输入来练习 Select-String,期望只输出一个匹配行,就像我通常在 echo -e ... | grep 组合中看到的那样。但是下面的命令仍然给我两行。似乎换行符只在最终输出中解释,Select-String 仍然得到一行输入

Write-Output "Hi`nthere" | Select-String -Pattern "i"
#
# Hi
# there
#
#

虽然我希望它 return 只是

Hi

我使用了这个版本的 PowerShell:

Get-Host | Select-Object Version
# 5.1.19041.906

bash 相比,我会在 bash 中执行以下测试多行输入命令的操作。我通常使用 echo -e 生成多行,然后 grep 处理各个行。

echo -e "Hi\nthere" | grep "i"
# Hi

我希望有人能解释一下我在 PowerShell 中遗漏了什么? 这个问题对我来说似乎是一个基本的误解,我也不确定要做什么 Google对于.

编辑

[编辑 1]: 以回车结尾的行也有问题 return

Write-Output "Hi`r`nthere" | Select-String -Pattern "i"

我看到用逗号分隔可以作为有效的多行输入。所以也许问题是如何从换行符转换为实际的输入行分隔符。

Write-Output "Hi","there" | Select-String -Pattern "i"
# Hi

[edit 2]: 来自 edit 1 我发现 ,对我来说它现在适用于

Write-Output "Hi`nthere".Split([Environment]::NewLine) | Select-String -Pattern "i"
# or
Write-Output "Hi`nthere".Split("`n") | Select-String -Pattern "i"

仍然有人可以解释为什么这与此处相关,但与 bash 无关?

所有信息都在评论里,我总结补充一下:

PowerShell 的管道是基于 object,并且 Select-String 对每个输入对象进行操作 - 即使这恰好是单个多行字符串对象,如Write-Output "Hi`nthere"

输出
  • 它只是外部程序的输出逐行

因此,您必须将多行字符串拆分成单独的行,以便这样匹配它们。

最好的用法是-split '\r?\n',因为它能识别Windows格式的 CRLF 和 Unix 格式的 LF-only 换行符:

"Hi`nthere" -split '\r?\n' | Select-String -Pattern "i"

注:

  • 我省略了 Write-Output 以支持 PowerShell 的 隐式 输出行为(有关详细信息,请参阅 的底部部分).

  • 有关 -split '\r?\n' 工作原理的更多信息,请参阅

  • Select-String直接输出匹配的行(字符串);相反,它将它们包装在 match-information objects 中,提供有关每个匹配项的元数据。仅获取匹配行(字符串):

    • PowerShell (Core) 7+ 中,添加 -Raw 开关。
    • Windows PowerShell 中,通过管道传输到 ForEach-Object Line 或将整个调用包装在 (...).Line