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

Nin*_*irl 529 powershell string-concatenation

假设我有以下代码段:

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

Write-host $assoc.Id + "  -  "  + $assoc.Name + "  -  " + $assoc.Owner
Run Code Online (Sandbox Code Playgroud)

我希望这段代码显示:

42 - Slim Shady - Eminem

但相反它显示:

42 + - + Slim Shady + - + Eminem

这让我觉得+运算符不适合连接字符串和变量.

您应该如何使用PowerShell进行此操作?

Dav*_*ant 585

Write-Host "$($assoc.Id) - $($assoc.Name) - $($assoc.Owner)"
Run Code Online (Sandbox Code Playgroud)

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

  • 这不是技术上的连接. (61认同)
  • @DannyStaple这个问题已经[编辑](http://stackoverflow.com/posts/15113413/revisions),以至于答案再也没有意义了.在苗条阴暗的例子中,是`"... $ name ..."`将完全相同,但在这个答案所针对的原始问题中,问题是如何访问对象属性.所以,如果`$ name.id -eq 42`然后``... $ name.id ......'`就不会像你想要的那样工作,因为它会呈现像`... {{id = 42} .id. ..`而不是想要的`... 42 ...`为此,使用答案的方法`"... $($ name.id)..."`.我正在将问题加入书签以便稍后编辑. (7认同)
  • 为什么$($ name)vs $ name?这是否与使用$ {name}的bash一样具有防御性? (4认同)
  • 这不适用于跨多行分布字符串。而是使用 `( $string1, $string2, $string3 ) -join ""` 或 `($string1 + $string2 + $string3)`。使用这些方法,您可以在字符串之间使用空格(空格、制表符和换行符),但请确保 (1) 每个字符串在同一行后面都有一个逗号/空格,(2) 您使用反勾号在代码之间的任何空行末尾添加字符 `,并且 (3) 如果使用 `-join`,则结束括号和 `-join` 运算符必须在同一行 (4认同)
  • 非常感谢您指点我的PowerShell语言规范.作为初学者,我一直很困惑为什么PowerShell没有附带官方教程.这个语言规范看起来像我正在寻找的.再次感谢! (3认同)
  • 你确定它在第34页吗?右下角是文字页还是页码?我查了两个地方都没有找到... (2认同)

Tin*_*oon 218

似乎没有人提到单引号和双引号之间的区别.(我使用的是PowerShell 4).

你可以这样做(正如@Ben所说):

$name = 'Slim Shady'
Write-Host 'My name is'$name
-> My name is Slim Shady
Run Code Online (Sandbox Code Playgroud)

或者你可以这样做:

$name = 'Slim Shady'
Write-Host "My name is $name"
-> My name is Slim Shady
Run Code Online (Sandbox Code Playgroud)

单引号用于文字,请输出完全相同的字符串.双引号用于何时需要进行一些预处理(例如变量,特殊字符等)

所以:

$name = "Marshall Bruce Mathers III"
Write-Host "$name"
-> Marshall Bruce Mathers III
Run Code Online (Sandbox Code Playgroud)

鉴于:

$name = "Marshall Bruce Mathers III"
Write-Host '$name'
-> $name
Run Code Online (Sandbox Code Playgroud)

(http://ss64.com/ps/syntax-esc.html我觉得很好参考).

  • 也适用于 1.0。 (2认同)

CB.*_*CB. 124

一种方法是:

Write-host "$($assoc.Id)  -  $($assoc.Name)  -  $($assoc.Owner)"
Run Code Online (Sandbox Code Playgroud)

另一个是:

Write-host  ("{0}  -  {1}  -  {2}" -f $assoc.Id,$assoc.Name,$assoc.Owner )
Run Code Online (Sandbox Code Playgroud)

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

Write-host $assoc.Id  "  -  "   $assoc.Name  "  -  "  $assoc.Owner
Run Code Online (Sandbox Code Playgroud)

  • 我不认为最后一个完全符合您的预期.请参见[pastebin here](http://pastebin.com/DD66QhCt).Powershell将为`$ assoc.Id`和```(等)之间的空格添加一个(即使你有两个)空格.也就是说,选项1给你`Id __-__ Name __-__ Owner`(每个`-`的每一边有两个空格,但选项3给出`Id ___-___ Name ___-___ Owner`(**三个**空格). (6认同)
  • [也许是一个更有用的pastebin](http://pastebin.com/Q0EcAkxR).`$ assoc.Id"###"$ assoc.Name`**将**添加到###两侧的空格,其中`"$($ assoc.Id)### $($ assoc.Name )"**不会**. (4认同)

man*_*ays 99

你也可以使用 -join

例如

$name = -join("Jo", "h", "n");
Run Code Online (Sandbox Code Playgroud)

将"John"分配给$ name.

所以输出,在一行:

Write-Host (-join("Jo", "h", "n"))
Run Code Online (Sandbox Code Playgroud)

  • 请补充一点,如果您使用命令作为输入,请将命令包装在 $().....例如... -join($(cmd1), ",", $(cmd2)) ...也带了我很想弄清楚,因为我是 powershell 新手 (4认同)
  • 至少这个可以用在 foreach 中 (2认同)

gor*_*ric 60

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

Write-host ($assoc.Id + "  -  "  + $assoc.Name + "  -  " + $assoc.Owner)
Run Code Online (Sandbox Code Playgroud)

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

  • 这个技巧是真正的串联,允许您执行多行字符串,就像在 .net 中一样。非常适合执行多行 SQL 语句!为什么 powershell 默认不这样做!? (3认同)
  • +1,我喜欢这种格式,当使用其他方法,如`Write-Debug`或`Write-Verbose`来包含双引号和变量值时,例如`Write-Debug('Running'cmdlet"with parameter $ MyVar ='+ $ MyVar +"at time"+(Get-Date -DisplayHint Time))` (2认同)
  • 是的,这就是字符串连接。它不会添加换行符或额外的空格。它允许您使用单引号或双引号字符串。 (2认同)

Fro*_* F. 28

另一种选择是:

$string = $assoc.ID
$string += " - "
$string += $assoc.Name
$string += " - "
$string += $assoc.Owner
Write-Host $string
Run Code Online (Sandbox Code Playgroud)

CB的建议可能是"最佳"方法:

Write-host "$($assoc.Id)  -  $($assoc.Name)  -  $($assoc.Owner)"
Run Code Online (Sandbox Code Playgroud)

  • 如果你要连续疯狂,你需要添加`StringBuilder`选项.; ^) (3认同)
  • 当然有一种方法可以将所需的属性传递到外部文件中,然后将它们反序列化为一个用连字符连接的组件串(?) (2认同)

Ric*_*ard 18

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

Write-host ($assoc.Id + "  -  "  + $assoc.Name + "  -  " + $assoc.Owner)
Run Code Online (Sandbox Code Playgroud)


Bil*_*ore 17

表达时:

"string1" + "string2" + "string3"
Run Code Online (Sandbox Code Playgroud)

将连接字符串.您需要在括号前面加上一个$,以便在传递给powershell命令时将其作为单个参数进行求值.例:

Write-Host $( "string1" + "string2" + "string3" ) 
Run Code Online (Sandbox Code Playgroud)

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

Write-Host $(`
    "The rain in "        +`
    "Spain falls mainly " +`
    "in the plains"       )`
    -ForegroundColor Yellow
Run Code Online (Sandbox Code Playgroud)

(实际上,我认为Powershell目前实现有点错误,需要在括号之间进行不必要的反差.如果微软只遵循"Python"或"TCL"括号规则,允许您在启动和启动之间放置任意数量的换行符.结束括号然后他们将解决人们不喜欢与线条延续相关的PowerShell的大多数问题,以及字符串的连接.我发现你可以在括号之间的线条延续上留下后面的勾号,但是如果能够工作的话真的很不稳定和不可预测..最好只添加反引号.)


Dav*_*ton 12

以下是另一种方式:

Write-host (" {0}  -  {1}  -  {2}" -f $assoc.Id, $assoc.Name, $assoc.Owner)
Run Code Online (Sandbox Code Playgroud)


Mar*_*ndl 9

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

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

  • @DineiRockenbach可能不是.只是想提出另一个例子. (4认同)
  • 使用 .NET `String.Format` 而不是旧的普通 `"{0}" -f $var` 有什么好处吗?我不认为使用 .NET 代码有什么意义,普通 PowerShell 可以完成这项工作...... (2认同)

Car*_*ten 7

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

[string]::Join(' - ', 42, 'Slim Shady', 'Eminem')
Run Code Online (Sandbox Code Playgroud)

或者基于具有不同属性类型的任何对象:

$assoc = [psCustomObject][ordered]@{
    Id    = 42
    Name  = 'Slim Shady'
    Owner = 'Eminem'
}
[string]::Join(' - ',$assoc.psObject.Properties.value)
Run Code Online (Sandbox Code Playgroud)

这给你这个结果:

42 - Slim Shady - Eminem
Run Code Online (Sandbox Code Playgroud)


E.V*_*.L. 6

PowerShell中的做/不做:第1部分:

$id = $assoc.Id
$name = $assoc.Name
$owner = $assoc.owner
"$id - $name - $owner"
Run Code Online (Sandbox Code Playgroud)


ele*_*8ed 6

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

$name = 'Slim Shady'
Write-Host 'My name is'$name
Run Code Online (Sandbox Code Playgroud)

它会输出

我的名字是Slim Shady

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


小智 6

就像在DOS时代一样,连接字符串。这对于日志记录来说意义重大,因此您可以开始以下操作:

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

Write-Output "$($strDate.Year)$($strDate.Month)$($strDate.Day)"
Write-Output $strday
Run Code Online (Sandbox Code Playgroud)


Ben*_*min 6

(当前PS版本5.1.17134.407)

我猜到现在所有的事情都说完了,但是到目前为止也可以使用:

$myVar = "Hello"

echo "${myVar} World"
Run Code Online (Sandbox Code Playgroud)


Luk*_*ett 5

每当我在远离PowerShell的情况下使用PowerShell时,我似乎都在为它(以及许多其他不直观的东西)而苦恼,因此我现在选择:

[string]::Concat("There are ", $count, " items in the list")
Run Code Online (Sandbox Code Playgroud)

  • 这将返回 System.Object,仅供参考。 (2认同)

Mor*_*hai 5

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

Write-Host $assoc.Id" - "$assoc.Name" - "$assoc.Owner
Run Code Online (Sandbox Code Playgroud)

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