805

假设我有以下片段:

$assoc = New-Object PSObject -Property @{
    Id = 42
    Name = "Slim Shady"
    Owner = "Eminem"
}

Write-Host $assoc.Id + "  -  "  + $assoc.Name + "  -  " + $assoc.Owner

我希望这个片段显示:

42 - Slim Shady - Eminem

但相反,它显示:

42 + - + Slim Shady + - + Eminem

这让我认为+运算符不适合连接字符串和变量。

你应该如何使用 PowerShell 来解决这个问题?

4

22 回答 22

873
Write-Host "$($assoc.Id) - $($assoc.Name) - $($assoc.Owner)"

请参阅Windows PowerShell 语言规范版本 3.0,p34,子表达式扩展。

于 2013-02-27T13:37:03.240 回答
343

单引号和双引号是有区别的。(我使用的是 PowerShell 4)。

你可以这样做(正如本杰明所说):

$name = 'Slim Shady'
Write-Host 'My name is'$name
-> My name is Slim Shady

或者你可以这样做:

$name = 'Slim Shady'
Write-Host "My name is $name"
-> My name is Slim Shady

单引号用于文字,请完全像这样输出字符串。双引号用于您想要完成一些预处理(例如变量,特殊字符等)

所以:

$name = "Marshall Bruce Mathers III"
Write-Host "$name"
-> Marshall Bruce Mathers III

然而:

$name = "Marshall Bruce Mathers III"
Write-Host '$name'
-> $name

(我发现How-to: Escape characters, Delimiters and Quotes非常适合参考)。

于 2015-09-08T10:25:22.393 回答
215

你也可以使用-join

例如

$var = -join("Hello", " ", "world");

将“Hello world”分配给 $var。

所以要输出,在一行中:

Write-Host (-join("Hello", " ", "world"))
于 2016-01-11T11:34:48.867 回答
146

一种方法是:

Write-Host "$($assoc.Id)  -  $($assoc.Name)  -  $($assoc.Owner)"

另一个是:

Write-Host  ("{0}  -  {1}  -  {2}" -f $assoc.Id,$assoc.Name,$assoc.Owner )

或者只是(但我不喜欢它;)):

Write-Host $assoc.Id  "  -  "   $assoc.Name  "  -  "  $assoc.Owner
于 2013-02-27T13:37:09.873 回答
89

尝试将要打印的任何内容包装在括号中:

Write-Host ($assoc.Id + "  -  "  + $assoc.Name + "  -  " + $assoc.Owner)

您的代码被解释为传递给的许多参数Write-Host。将其包裹在括号内将连接这些值,然后将结果值作为单个参数传递。

于 2013-02-27T13:37:39.453 回答
40

另一种选择是:

$string = $assoc.ID
$string += " - "
$string += $assoc.Name
$string += " - "
$string += $assoc.Owner
Write-Host $string

“最佳”方法可能是 CB 建议的一种:

Write-Host "$($assoc.Id)  -  $($assoc.Name)  -  $($assoc.Owner)"
于 2013-02-27T13:49:30.357 回答
32

虽然表达:

"string1" + "string2" + "string3"

将连接字符串,您需要在括号前面放一个 $ 以使其在传递给 PowerShell 命令时作为单个参数进行评估。例子:

Write-Host $( "string1" + "string2" + "string3" )

作为奖励,如果您希望它跨越多行,那么您需要在行尾使用笨拙的反引号语法(反引号右侧没有任何空格或字符)。

例子:

Write-Host $(`
    "The rain in "        +`
    "Spain falls mainly " +`
    "in the plains"       )`
    -ForegroundColor Yellow

(实际上,我认为 PowerShell 目前的实现有点错误,因为它需要括号之间不必要的反引号。如果 Microsoft 只是遵循PythonTcl括号规则,允许您在开始和结束括号之间放置任意数量的换行符,那么他们会解决了人们不喜欢 PowerShell 的大多数与行延续和字符串连接相关的问题。

我发现您有时可以在括号之间的行继续上保留反引号,但它是否会起作用真的很不稳定且不可预测......最好只添加反引号。)

于 2017-09-11T00:15:27.593 回答
30

您需要将表达式放在括号中,以防止它们被视为 cmdlet 的不同参数:

Write-Host ($assoc.Id + "  -  "  + $assoc.Name + "  -  " + $assoc.Owner)
于 2013-02-27T13:36:37.937 回答
14

这是另一种方法:

Write-Host (" {0}  -  {1}  -  {2}" -f $assoc.Id, $assoc.Name, $assoc.Owner)
于 2013-02-27T13:42:57.397 回答
14

(当前 PowerShell 版本 5.1.17134.407)

这也适用于现在:

$myVar = "Hello"

echo "${myVar} World"

注意:这只适用于双引号

于 2018-12-13T14:41:18.980 回答
10

我只想使用 .NET String.Format带来另一种方法:

$name = "Slim Shady"
Write-Host ([string]::Format("My name is {0}", $name))
于 2016-05-26T18:11:40.457 回答
8

每次使用 PowerShell 后,我似乎都在为这个(以及许多其他不直观的事情)而苦苦挣扎,所以我现在选择:

[string]::Concat("There are ", $count, " items in the list")
于 2017-04-19T08:23:11.400 回答
7

这些答案似乎都很复杂。如果您在 PowerShell 脚本中使用它,您可以简单地执行以下操作:

$name = 'Slim Shady'
Write-Host 'My name is'$name

它会输出

我的名字是苗条的阴影

请注意如何在您的单词之间放置空格

于 2015-05-05T21:21:57.857 回答
6

在 PowerShell 中做什么/不做什么:第 1 部分

$id = $assoc.Id
$name = $assoc.Name
$owner = $assoc.owner
"$id - $name - $owner"
于 2013-02-28T21:08:21.823 回答
6

就像在 DOS 时代一样连接字符串。这对于日志记录来说是一件大事,所以你去吧:

$strDate = Get-Date
$strday = "$($strDate.Year)$($strDate.Month)$($strDate.Day)"

Write-Output "$($strDate.Year)$($strDate.Month)$($strDate.Day)"
Write-Output $strday
于 2016-09-16T22:38:10.727 回答
5

Write-Host也可以像这样连接:

Write-Host $assoc.Id" - "$assoc.Name" - "$assoc.Owner

这是最简单的方法,恕我直言。

于 2017-05-22T17:05:08.430 回答
4

如果要连接字符串以构建文件路径,请使用Join-Path命令:

Join-Path C:\temp "MyNewFolder"

它会自动为您添加适当的尾随/前导斜杠,这使事情变得容易得多。

于 2019-12-05T19:11:28.173 回答
3
$assoc = @{
    Id = 34
    FirstName = "John"
    LastName = "Doe"
    Owner = "Wife"
}

$assocId = $assoc.Id
$assocFN = $assoc.FirstName
$assocLN = $assoc.LastName
$assocName = $assocFN, $assocLN -Join " "
$assocOwner = $assoc.Owner

$assocJoin = $assocId, $assocName, $assocOwner -join " - "
$assocJoin
#Output = 34 - John Doe - Wife
于 2019-02-22T17:11:57.377 回答
1

个人比较喜欢这种风格:

[string]::Join(' - ', 42, 'Slim Shady', 'Eminem')

或基于上述(无序)对象:

[string]::Join(' - ',$assoc.psObject.Properties.value)
于 2022-01-06T17:19:18.390 回答
0

只是为了好玩。您还可以直接访问 PSObject 的值,如下所示:

$assoc.psobject.Properties.value -join " - "

但是,如果您没有指定对象应该是有序的,PowerShell 将以随机顺序显示这些值。所以你应该添加标志[ordered]

$assoc = [pscustomobject] [ordered] @{
    Id = 42
    Name = "Slim Shady"
    Owner = "Eminem"
}
于 2019-02-12T14:53:21.373 回答
0

您还可以访问 C#/.NET 方法,以下内容也可以使用:

$string1 = "Slim Shady, "
$string2 = "The real slim shady"

$concatString = [System.String]::Concat($string1, $string2)

Output:

Slim Shady, The real slim shady
于 2020-04-20T12:59:42.770 回答
0

如其他地方所述,您可以使用 join。

如果您使用命令作为输入(就像我一样),请使用以下语法:

-join($(Command1), "," , $(Command2))

这将导致两个输出用逗号分隔。

相关评论见https://stackoverflow.com/a/34720515/11012871

于 2020-09-11T15:53:19.773 回答