迭代在这里的字符串中的子表达式导致额外的空格,为什么?

时间:2017-11-29 19:11:40

标签: powershell

问题

在PowerShell版本5.1.15063.726中运行以下内容

@"
$(foreach ($Number in 1..4) {"$Number`r`n"})
"@

结果

1
 2
 3
 4

在每一行的新行之后似乎添加了一个尾随空格。

Expirments

我想也许这是一个奇怪的

`r`n

但使用[Environment]::NewLine有同样的问题:

@"
$(foreach ($Number in 1..4) {"$Number" + [Environment]::NewLine})
"@

1
 2
 3
 4

在没有迭代的情况下做一些看似平等的事情按预期工作:

@"
$("1`r`n" + "2`r`n" + "3`r`n" + "4`r`n")
"@
1
2
3
4

以下也有效:

@"
$("1" + [Environment]::NewLine)$("2" + [Environment]::NewLine)$("3" + [Environment]::NewLine)$("4" + [Environment]::NewLine)
"@

@"
$("1`r`n")$("2`r`n")$("3`r`n")$("4`r`n")
"@

以下不起作用并导致新行后的奇数额外空格:

@"
$(1..4 | ForEach-Object {"$_`r`n"})
"@

@"
$(1..4 | ForEach-Object {$("$_`r`n")})
"@

解决方法

想一想这个问题可能与在循环中返回多个字符串有关,我试图构建一个字符串,然后返回那个有效的循环形式:

$String = ""
@"
$( foreach ($Number in 1..4) {$String += "$Number`r`n"}; $String)
"@
1
2
3
4

如果我们在从子表达式返回之前聚合字符串但在循环外进行聚合,则会返回相同的奇怪行为:

$String = ""
@"
$($String += foreach ($Number in 1..4) {"$Number`r`n"}; $String)
"@

1
 2
 3
 4

问题

任何人都知道造成这种情况的原因是什么?

2 个答案:

答案 0 :(得分:5)

默认输出字段分隔符是一个空格。您应该能够将$OFS设置为空字符串以获得您期望的结果。

答案 1 :(得分:1)

看起来它与输出系统的默认行为有关:

PS C:\> $z = "$(foreach ($Number in 1..4) {"$Number"})"
PS C:\> $z
1 2 3 4
PS C:\> [System.Text.Encoding]::ASCII.GetBytes($z)
49
32
50
32
51
32
52
PS C:\> $aa = "$(1..4)"
PS C:\> $aa
1 2 3 4
PS C:\> [System.Text.Encoding]::ASCII.GetBytes($aa)
49
32
50
32
51
32
52

32是空格的ASCII代码。

如果你需要进行复杂的字符串构造,我会使用StringBuilder