PowerShellで文字列と変数を連結するにはどうすればよいですか?


610

次のスニペットがあるとします。

$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でこれにどのように取り組むべきですか?


28
コードはすべての要素が文字列であり、式を括弧で囲んだ場合に機能します。 Write-host ($assoc.Id.ToString() + " - " + $assoc.Name + " - " + $assoc.Owner) ここで$ assoc.IdはInt32なので、その文字列表現を使用する必要があります。それ以外の場合、PSは連結ではなく算術加算を実行しようとします。
bouvierr 2013年

5
私の編集が内容をかなり変えたとしても、私はこの質問のテキストを修正することが適切であると私は考えたビューの数を考えて。再開できるように十分に改善しながら、用語/文言と質問の精神を損なわないように努めました。
Jeroen

回答:


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

Windows PowerShell言語仕様バージョン3.0、p34、部分式展開を参照してください。


1
この手法はWrite-Output et alでも機能するので、ツールボックスで使用するのがおそらく最も便利です。
Fenton、2015

4
なぜ$($ name)対$ nameなのですか?これは、$ {name}を使用するbashと同じように防御的ですか?
ダニーステープル2016

73
これは技術的には連結ではありません。
TravisEz13

8
@DannyStaple質問が編集されすぎているため、回答が意味をなさなくなりました。スリムな怪しげな例では、yes "... $name ..."はすべて同じように機能しますが、この回答が対処する元の質問では、問題はオブジェクトのプロパティにアクセスする方法です。そうであれば$name.id -eq 42、その後"... $name.id ..."、それは次のようにレンダリングされますので、あなたが望むように動作しない... @{id=42}.id ...代わりに、希望の... 42 ...、そのための答えのメソッドを使用します"... $($name.id) ..."。質問をブックマークして後で編集します。
Jeff Puckett 2016年

3
PowerShell言語仕様を指定していただき、ありがとうございます。私は初心者として、PowerShellに公式のチュートリアルが付属していない理由について常に混乱していました。この言語仕様は私が探しているもののように見えます。再度、感謝します!
RayLuo 2016年

256

一重引用符と二重引用符の違いに言及した人はいません。(私はPowerShell 4を使用しています)。

これを行うことができます(@Benが言ったように):

$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

http://ss64.com/ps/syntax-esc.html参考にしてください)。


1
1.0でも動作します。
Smit Johnth

134

1つの方法は次のとおりです。

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

7
最後の1つは期待どおりに機能するとは思わない。こちらのペーストビンを参照してください。Powershellは、$assoc.Id"(et al)の間の空白のために、出力に1つ(ここでは2つあります)のスペースを追加します。つまり、オプション1はId__-__Name__-__Owner(それぞれの両側に2 つのスペース)-を提供しますが、オプション3はId___-___Name___-___Owner3つのスペース)を提供します。
ruffin

4
おそらくもっと便利なペーストビン。###の両側にスペースを追加します$assoc.Id"###"$assoc.Name が、追加"$($assoc.Id)###$($assoc.Name)" されません
ruffin 2014

1
2つ目は、Powershellが私の目的に必要なものだと確信しました-ありがとう
MaVCArt

123

あなたも使うことができます -join

例えば

$name = -join("Jo", "h", "n");

$ nameに "John"を割り当てます。

したがって、出力するには、1行で:

Write-Host (-join("Jo", "h", "n"))

少なくともこれはforeachで使用できます
dEmigOd

68

印刷したいものはすべて括弧で囲んでください。

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

コードは、に渡される多くのパラメータとして解釈されていますWrite-Host。括弧で囲んで値を連結し、結果の値を単一のパラメーターとして渡します。


3
以下のような他の方法を使用している場合+1は、私は、この形式を好むWrite-DebugWrite-Verboseのような二重引用符と変数値、などのためにWrite-Debug ('Running "cmdlet" with parameter $MyVar = ' + $MyVar + " at time " + (Get-Date -DisplayHint Time))
ITベアを

はい、これは文字列の連結です。改行や余分なスペースは追加されません。単一引用符または二重引用符で囲まれた文字列を使用できます。
LexieHankins

このトリックは真の連結であり、.netの場合のように複数行の文字列を実行できます。複数行のSQLステートメントの実行に非常に適しています。powershellがデフォルトでこれを行わないのはなぜですか?
Brain2000

これには多くの方法があります。しかし、これが文字列連結の正解です。
chingNotCHing

32

別のオプションは次のとおりです。

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

「最良の」方法は、おそらくCBが提案したものです。

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

3
StringBuilder狂ったように行く場合は、オプションを追加する必要があります。; ^)
ruffin 2014

2
確かにパイプの方法は、外部ファイルに所望の特性は、次にハイフンで結合構成成分の列にそれらをデシリアライズがある(?)
コードジョッキー

これよりも悪いアプローチを想像するのは難しい。文字列は不変であるため、各連結操作は実際には新しい文字列を生成し、元の文字列の文字をコピーします。
wombatonfire 2018年

22

コマンドレットの異なるパラメーターとして扱われないようにするには、式を括弧で囲む必要があります。

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

これは書き込みデバッグに必須です
フランク

19

表現中:

"string1" + "string2" + "string3"

文字列を連結します。かっこの前に$を付けて、Powershellコマンドに渡されたときに単一の引数として評価されるようにする必要があります。例:

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

おまけとして、複数行にまたがるようにしたい場合は、行末にバックワードシンタックス構文を使用する必要があります(バックチックの右側にスペースや文字はありません)。例:

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

(実際には、Powershellは現在、括弧の間に不必要なバックティックを必要とするため、少し間違って実装されていると思います。Microsoftが「Python」または「TCL」の括弧ルールに従って、開始と開始の間に必要なだけの改行を入れることができる場合かっこを終了すると、行の継続と文字列の連結に関連するPowerShellについて人々が気に入らない問題のほとんどが解決されます。かっこ間の行の継続では、バックティックをオフにしておくことができますが、それが機能する場合、本当に不安定で予測不可能です。バッククォートを追加することをお勧めします。)



9

.NET String.Formatを使用してこれを行う別の方法を提供したいだけです:

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

2
String.Format古いプレーンの代わりに.NETを使用する利点はあります"{0}" -f $varか?.NETコードを使用して、単純なPowerShellで処理を実行できるポイントがわかりません...
Dinei 2017年

4
@DineiRockenbachおそらく違います。別の例を挙げたかっただけです。
Martin Brandl 2017年

9

(現在のPSバージョン5.1.17134.407)

それはすべて今までに言われ終わったと思いますが、これは今のところうまくいきます:

$myVar = "Hello"

echo "${myVar} World"

注:これは二重引用符でのみ機能します


7

これらの答えはすべて非常に複雑に見えます。これをPowerShellスクリプトで使用している場合は、次のようにするだけです。

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

出力されます

私の名前はスリムシェイディです

単語の間にスペースが挿入されていることに注意してください



6

DOS日と同じように文字列を連結します。これはロギングにとって重要なので、次のようにします。

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

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

日付のために、私が思うにtoStringオプションは簡単です:(Get-Date).toString('yyyyMMdd')
トニー

6

私は、PowerShellを離れて使用するたびにこれ(および他の多くの直感的でないもの)に苦労しているようです。

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

1
これは、System.Object、fyiを返します。
バリー


2
$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

2

文字列を連結してファイルパスを構築する場合は、join-pathコマンドを使用します。

join-path C:\temp "MyNewFolder"

自動的に適切な末尾/先頭のスラッシュが追加されるので、物事がずっと簡単になります。

これが話題から外れていることをお詫び申し上げますが、一部の参考になると思いました。
PowerShellをしばらく使用しないと、存在することを忘れて連結演算子の検索を開始することがあります。


0

C#/。NETメソッドへのアクセスを取得することもでき、以下も機能します。

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

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

Output:

Slim Shady, The real slim shady

-2

ちょうど楽しみのために。以下のように、PSObjectの値に直接アクセスすることもできます。

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

ただし、オブジェクトを順序付ける必要があることを指定しない場合、Powershellは値をランダムな順序で表示します。フラグを追加する必要があります[順序]

$assoc = [pscustomobject] [ordered] @{
    Id = 42
    Name = "Slim Shady"
    Owner = "Eminem"
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.