如何在PowerShell中连接字符串和变量?

假设我有以下代码片段:

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

我希望这个片段显示:

42 - Slim Shady - Eminem

相反,它显示:

42 + - + Slim Shady + - + Eminem

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

如何使用PowerShell解决这个问题?

2032931 次浏览

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

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

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

一种方法是:

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

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

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

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

这里有另一种方法作为替代:

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

另一种选择是:

$string = $assoc.ID$string += " - "$string += $assoc.Name$string += " - "$string += $assoc.OwnerWrite-Host $string

“最佳”方法可能是C. B.建议的:

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

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

$id = $assoc.Id$name = $assoc.Name$owner = $assoc.owner"$id - $name - $owner"

这些答案看起来都非常复杂。如果您在PowerShell脚本中使用它,您可以简单地执行以下操作:

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

它将输出

我叫Slim Shady

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

单引号和双引号之间存在差异。(我使用的是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

(我发现操作方法:转义字符、分隔符和引号很适合参考)。

您也可以使用-join

例如。

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

将“Hello world”分配给$var。

所以要输出,在一行中:

Write-Host (-join("Hello", " ", "world"))

我只是想用另一种方法来做到这一点。NET字符串格式

$name = "Slim Shady"Write-Host ([string]::Format("My name is {0}", $name))

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

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

每次使用PowerShell后,我似乎都在努力解决这个问题(以及许多其他不直观的事情),所以我现在选择:

[string]::Concat("There are ", $count, " items in the list")

写入主机也可以像这样连接:

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

这是最简单的方法,IMHO。

而表达式:

"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的大多数与行延续和字符串连接有关的问题。

我发现你可以离开反引号有时在括号之间的行延续,但它真的是片状的和不可预测的,如果它会工作……最好只是添加反引号。

(当前PowerShell版本5.1.17134.407)

这也适用于现在:

$myVar = "Hello"
echo "${myVar} World"

注意:这只适用于双引号

只是为了好玩。您也可以像下面这样直接访问PSObject的值:

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

但是,如果您没有指定应该对对象进行排序,PowerShell将以随机顺序显示值。因此,您应该添加标志[ordered]

$assoc = [pscustomobject] [ordered] @{Id = 42Name = "Slim Shady"Owner = "Eminem"}
$assoc = @{Id = 34FirstName = "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

如果您要连接字符串以构建文件路径,请使用加入路径命令:

Join-Path C:\temp "MyNewFolder"

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

您还可以访问C#/。NET方法,以下方法也有效:

$string1 = "Slim Shady, "$string2 = "The real slim shady"
$concatString = [System.String]::Concat($string1, $string2)
Output:
Slim Shady, The real slim shady

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

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

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

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

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

我个人比较喜欢这种风格:

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

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

[string]::Join(' - ',$assoc.psObject.Properties.value)