ฉันจะเชื่อมสตริงและตัวแปรใน PowerShell ได้อย่างไร


609

สมมติว่าฉันมีตัวอย่างต่อไปนี้:

$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) here $ assoc.Id คือInt32สิ่งที่เราต้องใช้ในการแสดงสตริง มิฉะนั้น PS จะพยายามทำการบวกเลขคณิตแทนการต่อข้อมูล
bouvierr

5
เมื่อพิจารณาจากจำนวนการดูฉันคิดว่ามันเหมาะสมที่จะแก้ไขข้อความของคำถามนี้แม้ว่าการแก้ไขของฉันจะเปลี่ยนเนื้อหาไปเล็กน้อย ฉันพยายามเก็บคำศัพท์ / ถ้อยคำและจิตวิญญาณของคำถามเอาไว้ในขณะที่ปรับปรุงให้ดีพอที่จะเปิดใหม่ได้
Jeroen

คำตอบ:


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

ดูส่วนขยายข้อมูลจำเพาะภาษา Windows PowerShell รุ่น 3.0 , p34, นิพจน์ย่อย


1
เทคนิคนี้ใช้ได้กับWrite-Output et alด้วยดังนั้นอาจเป็นวิธีที่มีประโยชน์มากที่สุดในกล่องเครื่องมือของคุณ
เฟนตัน

4
ทำไม $ ($ name) เทียบกับแค่ $ name? นี่เป็นเพียงการป้องกันในลักษณะเดียวกับในทุบตีโดยใช้ $ {name}?
Danny Staple

73
นี่ไม่ใช่การต่อข้อมูลทางเทคนิค
TravisEz13

8
@DannyStaple คำถามถูกแก้ไขมากจนคำตอบไม่สมเหตุสมผลอีกต่อไป ในตัวอย่างแบบเบาบางใช่"... $name ..."จะทำงานเหมือนกันทั้งหมด แต่ในคำถามเดิมที่คำตอบนี้ตอบคำถามคือวิธีเข้าถึงคุณสมบัติของวัตถุ ดังนั้นหาก$name.id -eq 42แล้ว"... $name.id ..."จะไม่ทำงานเหมือนที่คุณต้องการเพราะมันจะทำให้เหมือน... @{id=42}.id ...แทนที่ต้องการเพื่อที่ใช้วิธีการที่คำตอบของ... 42 ... "... $($name.id) ..."ฉันกำลังบุ๊คมาร์คคำถามเพื่อแก้ไขในภายหลัง
Jeff Puckett

3
ขอบคุณมากที่ชี้นำฉันไปที่ข้อมูลจำเพาะภาษา PowerShell ในฐานะผู้เริ่มต้นฉันสับสนอยู่เสมอว่าทำไม PowerShell จึงไม่มาพร้อมกับบทแนะนำอย่างเป็นทางการ ข้อมูลจำเพาะภาษานี้ดูเหมือนว่าฉันกำลังมองหา ขอบคุณอีกครั้ง!
RayLuo

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

วิธีหนึ่งคือ:

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
ฉันไม่คิดว่าอันสุดท้ายจะได้ผลตามที่คุณคาดหวัง ดูPastebin ที่นี่ Powershell จะเพิ่มพื้นที่หนึ่ง (แม้ว่าคุณจะมีสองที่นี่) ลงในเอาต์พุตสำหรับช่องว่างระหว่าง$assoc.Idและ"(et al) นั่นคือตัวเลือกที่ 1 ให้คุณId__-__Name__-__Owner(ช่องว่างสองด้านในแต่ละด้านของแต่ละด้าน-) แต่ตัวเลือก 3 ให้Id___-___Name___-___Owner( ช่องว่างสามช่อง)
ruffin

4
อาจเป็นประโยชน์ต่อการวาง $assoc.Id"###"$assoc.Name จะเพิ่มช่องว่างด้านข้างของ ### อย่างใดอย่างหนึ่งที่จะไม่"$($assoc.Id)###$($assoc.Name)"
ruffin

1
คนที่สองทำให้ฉันเชื่อว่าสิ่งที่ฉันต้องการคือพลังของฉัน - ขอบคุณ!
MaVCArt

123

คุณยังสามารถใช้ -join

เช่น

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

จะกำหนด "John" เป็นชื่อ $

ดังนั้นในบรรทัดเดียว:

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

อย่างน้อยอันนี้สามารถใช้ใน foreach
dEmigOd

68

ลองห่อสิ่งที่คุณต้องการพิมพ์ในวงเล็บ:

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

Write-Hostรหัสของคุณจะถูกตีความว่าเป็นปัจจัยหลายประการที่จะถูกส่งผ่านไปยัง การห่อมันไว้ในวงเล็บจะทำการเชื่อมค่าแล้วส่งค่าผลลัพธ์เป็นพารามิเตอร์เดียว


3
+1, ฉันชอบรูปแบบนี้เมื่อใช้วิธีอื่นเช่นWrite-DebugหรือWrite-Verboseรวมถึงเครื่องหมายคำพูดคู่และค่าตัวแปรเช่นWrite-Debug ('Running "cmdlet" with parameter $MyVar = ' + $MyVar + " at time " + (Get-Date -DisplayHint Time))
IT Bear

ใช่นี่คือการต่อสตริง มันไม่ได้เพิ่มบรรทัดใหม่หรือช่องว่างพิเศษ มันช่วยให้คุณใช้สายเดียวหรือสองครั้งที่ยกมา
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

2
แน่นอนมีวิธีการไพพ์คุณสมบัติที่ต้องการลงในไฟล์ภายนอกจากนั้นทำการดีซีเรียลไลซ์ลงในสตริงของส่วนประกอบที่รวมกับยัติภังค์ (?)
Code Jockey

มันยากที่จะจินตนาการถึงสิ่งที่เลวร้ายยิ่งกว่านี้ สตริงไม่สามารถเปลี่ยนแปลงได้ดังนั้นการดำเนินการเรียงต่อกันแต่ละอันจะสร้างสตริงใหม่โดยคัดลอกอักขระของต้นฉบับ
wombatonfire

22

คุณจำเป็นต้องวางนิพจน์ในวงเล็บเพื่อหยุดการถูกถือว่าเป็นพารามิเตอร์ที่แตกต่างไปยัง cmdlet:

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

นี่เป็นข้อบังคับสำหรับ Write-Debug
Frank

19

ในขณะที่การแสดงออก:

"string1" + "string2" + "string3"

จะต่อสายเข้าด้วยกัน คุณต้องใส่ $ ไว้ข้างหน้าวงเล็บเพื่อให้ประเมินเป็นอาร์กิวเมนต์เดี่ยวเมื่อส่งผ่านไปยังคำสั่ง powershell ตัวอย่าง:

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

เป็นโบนัสหากคุณต้องการให้ขยายหลายบรรทัดคุณต้องใช้ไวยากรณ์ backtick ackward ที่ท้ายบรรทัด (โดยไม่มีช่องว่างหรืออักขระทางด้านขวาของ backtick) ตัวอย่าง:

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

(อันที่จริงฉันคิดว่า Powershell มีการใช้งานผิดเล็กน้อยโดยต้องการการย้อนกลับโดยไม่จำเป็นระหว่างวงเล็บถ้า Microsoft เพียงแค่ทำตาม "Python" หรือ "TCL" กฎของวงเล็บที่อนุญาตให้คุณใส่บรรทัดใหม่ได้มากเท่าที่คุณต้องการระหว่างเริ่มต้นและ วงเล็บปิดแล้วพวกเขาก็จะแก้ปัญหาส่วนใหญ่ที่คนไม่ชอบเกี่ยวกับ powershell ที่เกี่ยวข้องกับความต่อเนื่องของเส้นและการต่อสายฉันพบว่าคุณสามารถปล่อยให้เห็บกลับมาบางครั้งบนเส้นต่อเนื่องระหว่างวงเล็บ น่ากลัวและคาดเดาไม่ได้ถ้ามันจะได้ผล .. มันดีกว่าที่จะเพิ่ม backticks)



9

ฉันต้องการนำวิธีอื่นในการทำสิ่งนี้โดยใช้. NET String รูปแบบ :

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

2
มีข้อได้เปรียบของการใช้. NET String.Formatแทนที่จะเป็นแบบธรรมดา"{0}" -f $varหรือไม่ ฉันไม่เห็นจุดในการใช้รหัส .NET ที่ธรรมดา PowerShell สามารถทำผลงานได้ ...
Dinei

4
@DineiRockenbach อาจจะไม่ แค่อยากจะยกตัวอย่างอีก
Martin Brandl

9

(รุ่น PS ปัจจุบัน 5.1.17134.407)

ทุกอย่างพูดแล้วเสร็จตอนนี้ฉันเดา แต่ตอนนี้ก็ใช้ได้เหมือนตอนนี้:

$myVar = "Hello"

echo "${myVar} World"

หมายเหตุ: ใช้ได้กับเครื่องหมายคำพูดคู่เท่านั้น


7

คำตอบเหล่านี้ดูเหมือนจะซับซ้อนมาก หากคุณกำลังใช้สิ่งนี้ในสคริปต์ PowerShell คุณสามารถทำได้ดังนี้:

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

มันจะออก

ฉันชื่อ 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

6

ฉันดูเหมือนจะต่อสู้กับสิ่งนี้ (และสิ่งอื่น ๆ ที่ไม่ได้ใช้งานง่าย) ทุกครั้งที่ฉันใช้ PowerShell หลังจากเวลาผ่านไปดังนั้นฉันจึงเลือก:

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

1
สิ่งนี้จะคืนค่า System.Object, fyi
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

หากคุณกำลังต่อสตริงเพื่อสร้างพา ธ ไฟล์ให้ใช้คำสั่ง join-path:

join-path C:\temp "MyNewFolder"

มันจะเพิ่มเครื่องหมายทับ / นำที่เหมาะสมสำหรับคุณโดยอัตโนมัติซึ่งทำให้สิ่งต่าง ๆ ง่ายขึ้นมาก

ฉันขอโทษถ้านี่เป็นหัวข้อนอกเกินไป แต่ฉันคิดว่ามันอาจช่วยบางอย่าง
หากฉันไม่ได้ใช้ PowerShell สักพักบางครั้งฉันก็จะลืมมันไปแล้วเริ่มค้นหาผู้ดำเนินการเชื่อมต่อ



-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.