PowerShell'de dizeleri ve değişkenleri nasıl birleştirebilirim?


609

Aşağıdaki snippet'e sahip olduğumu varsayalım:

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

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

Bu pasajın şunu göstermesini beklerdim:

42 - Slim Shady - Eminem

Ama bunun yerine şunu gösterir:

42 + - + Slim Shady + - + Eminem

Bu da +operatörün dizeleri ve değişkenleri birleştirmek için uygun olmadığını düşündürüyor .

PowerShell ile buna nasıl yaklaşmalısınız?


28
Kodunuz çalışır eğer : tüm elemanlar dizeleri ve parantez içinde ifadeyi kapamak Write-host ($assoc.Id.ToString() + " - " + $assoc.Name + " - " + $assoc.Owner) burada $ assoc.Id bir olduğunu Int32biz onun dize temsilini kullanmak zorunda. Aksi takdirde PS, birleştirme yerine aritmetik bir ekleme yapmaya çalışır.
bouvierr

5
Görüşlerim göz önüne alındığında, düzenlemelerim içeriği biraz değiştirse bile, bu sorunun metnini onarmanın uygun olduğunu düşündüm. Sorunun terminolojisini / ifadesini ve ruhunu sağlam tutmaya çalıştım, aynı zamanda tekrar açılabilmesi için yeterince geliştirdim.
Jeroen

Yanıtlar:


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

Bkz. Windows PowerShell Dil Belirtimi Sürüm 3.0 , p34, alt ifadeler genişletmesi.


1
Bu teknik Write-Output et al ile de çalışır , bu nedenle araç kutunuzda olması muhtemelen en yararlı olanıdır.
Fenton

4
Neden $ ($ name) vs $ $? Bu sadece $ {name} kullanan bash ile aynı şekilde savunuyor mu?
Danny Staple

73
Bu teknik olarak birleştirme değildir.
TravisEz13

8
@DannyStaple, soru o kadar çok düzenlendi ki, cevap artık bir anlam ifade etmiyor. İnce gölgeli örnekte, evet "... $name ..."aynı şekilde çalışacaktır, ancak bu cevabın ele aldığı orijinal soruda, nesne özelliklerine nasıl erişileceği sorusudur. eğer öyleyse $name.id -eq 42o zaman "... $name.id ..."o gibi işlemek çünkü istediğiniz gibi işe yaramaz ... @{id=42}.id ...yerine arzu ait ... 42 ..., Bunun için cevabım yöntemi kullanmak "... $($name.id) ...". Daha sonra düzenlemek için sorulara yer işareti koyuyorum.
Jeff Puckett

3
Beni PowerShell Dil Spesifikasyonuna yönlendirdiğiniz için çok teşekkürler. Yeni başlayanlar olarak, PowerShell'in neden resmi bir öğretici ile gelmediği konusunda her zaman kafam karıştı. Bu dil özelliği aradığım şey gibi görünüyor. Tekrar teşekkürler!
RayLuo

256

Hiç kimse tek ve çift tırnaklar arasındaki farktan bahsetmemiş gibi görünüyor. (PowerShell 4 kullanıyorum).

Bunu yapabilirsiniz (@Ben'in söylediği gibi):

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

Veya bunu yapabilirsiniz:

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

Tek tırnak kelimenin tam anlamıyla içindir, dizeyi aynen bu şekilde çıktılar, lütfen. Çift tırnak işaretleri, bazı ön işlemlerin (değişkenler, özel karakterler vb.) Yapılmasını istediğinizde kullanılır

Yani:

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

Buna karşılık:

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

( http://ss64.com/ps/syntax-esc.html Başvuru için iyi buluyorum).


1
1.0 ile de çalışır.
Smit Johnth

134

Bunun bir yolu:

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

Bir diğeri:

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

Veya sadece (ama sevmiyorum;)):

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

7
Sonuncusunun tam olarak beklediğiniz gibi çalıştığını sanmıyorum. Bkz buraya pastebin . Powershell, $assoc.Idve "(et al) arasındaki boşluk için çıktıya bir (burada iki tane olsa bile) alan ekleyecektir . Yani, seçenek 1 size Id__-__Name__-__Owner(her iki tarafta iki boşluk -) verir, ancak seçenek 3 Id___-___Name___-___Owner( üç boşluk) verir .
14'te

4
Belki daha kullanışlı bir macun . $assoc.Id"###"$assoc.Name olacak ### her iki tarafına da boşluk eklemek, burada "$($assoc.Id)###$($assoc.Name)" olmaz .
14'te

1
ikincisi beni powershell benim amaçlarım için gerekli olan şey - ikna etti!
MaVCArt

123

Ayrıca kullanabilirsiniz -join

Örneğin

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

$ Adına "John" atar.

Çıktı için, bir satırda:

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

en azından bu foreach
dEmigOd

68

Parantez içinde yazdırmak istediğiniz her şeyi sarmayı deneyin:

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

Kodunuz iletilen birçok parametre olarak yorumlanıyor Write-Host. Parantez içine alınması, değerleri birleştirir ve sonuçta elde edilen değeri tek bir parametre olarak iletir.


3
+1, ben çift ​​tırnak ve değişken değerleri gibi Write-Debugveya gibi diğer yöntemleri kullanırken bu biçimi tercih ederim Write-Verbose, örneğinWrite-Debug ('Running "cmdlet" with parameter $MyVar = ' + $MyVar + " at time " + (Get-Date -DisplayHint Time))
IT Bear

Evet, bu dize birleşimidir. Yeni satır veya fazladan boşluk eklemez. Tek veya çift tırnaklı dizeler kullanmanızı sağlar.
LexieHankins

Bu hile gerçek birleştirme ve .net gibi çok satırlı dizeler yapmanızı sağlar. Çok satırlı SQL ifadeleri yapmak için çok iyi! Powershell bunu neden varsayılan olarak yapmıyor !?
Brain2000

Yapmanın birçok yolu var. Ancak bu, dize birleştirmenin gerçek cevabıdır.
chingNotCHing

32

Başka bir seçenek:

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

"En iyi" yöntem muhtemelen CB'nin önerdiği yöntemdir:

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

3
Eğer StringBuilderçılgınca gidiyorsanız seçeneği eklemeniz gerekir . ; ^)
14'te ruffin

2
elbette, istenen özellikleri harici bir dosyaya aktarmanın bir yolu var, daha sonra bunları tirelerle birleştirilen bir dizi diziye serileştirin (?)
Kod Jokey

Bundan daha kötü bir yaklaşım hayal etmek zor. Dizeler değişmezdir, bu nedenle her bir birleştirme işlemi aslında orijinal dizinin karakterlerini kopyalayarak yeni bir dize üretir.
wombatonfire

22

Cmdlet'e farklı parametreler olarak muamele edilmesini durdurmak için ifadeyi parantez içine almanız gerekir:

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

Bu, Write-Debug için zorunludur
Frank

19

İfade ederken:

"string1" + "string2" + "string3"

dizeleri birleştirir. Bir powershell komutuna iletildiğinde, tek bir argüman olarak değerlendirilebilmesi için parantezin önüne bir $ koymanız gerekir. Misal:

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

Bir bonus olarak, birden fazla satıra yayılmasını istiyorsanız, satırın sonunda sabit backtick sözdizimini kullanmanız gerekir (backtick'in sağında boşluk veya karakter olmadan). Misal:

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

(Aslında, Powershell'in şu anda parantez arasında gereksiz geri işaretler gerektirmesi nedeniyle biraz yanlış uygulandığını düşünüyorum. Microsoft, sadece "Python" veya "TCL" Parantez kurallarını izleyerek başlangıç ​​ve ara arasında istediğiniz kadar yeni satır koymanıza izin verir. Parantez sonlandırıldığında, insanların hat devam ettirme ve dizelerin birleştirilmesiyle ilgili powershell ile ilgili sevmedikleri sorunların çoğunu çözeceklerdi.Bazenleri parantez arasındaki satır devamlarında bırakabileceğinizi gördüm, ancak gerçekten lapa lapa ve eğer işe yaramazsa öngörülemez .. sadece backticks eklemek daha iyi.)


13

Alternatif olarak başka bir yol:

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

9

Sadece .NET String.Format kullanarak bunu yapmak için başka bir yol getirmek istiyorum :

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

2
String.FormatEski düz yerine .NET kullanmanın herhangi bir avantajı var mı "{0}" -f $var? Düz PowerShell'in işi yapabileceği .NET kodunu kullanma noktasını görmüyorum ...
Dinei

4
@DineiRockenbach Muhtemelen hayır. Başka bir örnek daha getirmek istedim.
Martin Brandl

9

(Mevcut PS sürümü 5.1.17134.407)

Her şey söyleniyor ve şimdiye kadar yapıldı sanırım ama bu şu an itibariyle de çalışıyor:

$myVar = "Hello"

echo "${myVar} World"

Not: Bu sadece çift tırnak işareti ile çalışır


7

Bu cevapların hepsi çok karmaşık görünüyor. Bunu bir PowerShell betiğinde kullanıyorsanız bunu yapabilirsiniz:

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

Çıktı verecek

Benim adım Slim Shady

Kelimeler arasında sizin için nasıl bir boşluk bırakıldığına dikkat edin



6

DOS günlerinde olduğu gibi dizeleri birleştirin. Bu, giriş yapmak için büyük bir anlaşma, işte burada:

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

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

Tarihler için, bence toStringseçenek daha kolay:(Get-Date).toString('yyyyMMdd')
Tony

6

Bundan sonra PowerShell'i her kullandığımda (ve diğer birçok sezgisel olmayan şeyle) mücadele ediyorum, bu yüzden şimdi tercih ediyorum:

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

1
bu System.Object, fyi döndürür.
Barry


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

Dosya yollarını oluşturmak için dizeleri birleştiriyorsanız, join-path komutunu kullanın:

join-path C:\temp "MyNewFolder"

Sizin için uygun sondaki / önde gelen eğik çizgileri otomatik olarak ekler, bu da işleri daha kolay hale getirir.

Bu çok konu dışı olduğunda özür dilerim, ama bazılarına yardımcı olabileceğini düşündüm.
Bir süre PowerShell kullanmazsam, bazen var olduğunu unutabilir ve birleştirme işleçlerini aramaya başlarım.


0

Ayrıca C # /. NET yöntemlerine erişebilirsiniz ve aşağıdakiler de çalışır:

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

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

Output:

Slim Shady, The real slim shady

-2

Sadece eğlence için. PSObject değerlerine doğrudan aşağıdaki gibi de erişebilirsiniz:

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

Ancak, nesnenin sipariş edilmesi gerektiğini belirtmezseniz, Powershell değerleri rastgele sırada görüntüler. Bayrak eklemelisiniz [sıralı]

$assoc = [pscustomobject] [ordered] @{
    Id = 42
    Name = "Slim Shady"
    Owner = "Eminem"
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.