मैं 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) जोड़ते हैं : यहाँ $ assoc.Id है Int32इसलिए हमें इसके स्ट्रिंग प्रतिनिधित्व का उपयोग करना होगा। अन्यथा PS संघनन के बजाय अंकगणितीय जोड़ के प्रदर्शन की कोशिश करता है।
22

5
मेरे विचार की संख्या को देखते हुए इस प्रश्न के पाठ को ठीक करना उचित था, हालांकि मेरे संपादन ने सामग्री को थोड़ा बदल दिया। मैंने प्रश्न की शब्दावली / शब्द और आत्मा को अक्षुण्ण रखने की कोशिश की है, जबकि इसे पर्याप्त सुधार दिया है ताकि इसे फिर से खोला जा सके।
जेरोन

जवाबों:


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

देखें विंडोज PowerShell भाषा विशिष्टता संस्करण 3.0 , P34, उप भाव विस्तार।


1
यह तकनीक Write-Output एट अल के साथ भी काम करती है, इसलिए यह संभवतः आपके टूलबॉक्स में सबसे उपयोगी है।
फेंटन

4
$ ($ नाम) बनाम सिर्फ $ नाम क्यों? क्या यह उसी तरह रक्षात्मक है जैसे $ {name} का उपयोग करके बैश में?
डैनी स्टैपल

73
यह तकनीकी रूप से सहमति नहीं है।
ट्रैविज़ेज़ 13

8
@DannyStaple प्रश्न को इतना अधिक संपादित किया गया है कि उत्तर का कोई मतलब नहीं है। स्लिम छायादार उदाहरण में, हाँ "... $name ..."सभी समान काम करेंगे, लेकिन मूल प्रश्न में जिसके लिए यह उत्तर देता है, सवाल यह है कि गुणों को कैसे एक्सेस करें। यदि ऐसा है तो $name.id -eq 42फिर "... $name.id ..."जैसे आप चाहते हैं, क्योंकि यह की तरह प्रस्तुत करना होगा कार्य नहीं करेगा ... @{id=42}.id ...वांछित के बजाय ... 42 ...उसके लिए, इस सवाल का जवाब की विधि का उपयोग करें "... $($name.id) ..."। बाद में संपादित करने के लिए मैं बुकमार्क बुकमार्क कर रहा हूं।
जेफ पुकेट

3
मुझे PowerShell भाषा विनिर्देश की ओर इशारा करने के लिए बहुत बहुत धन्यवाद। एक शुरुआत के रूप में, मैं हमेशा इस बारे में उलझन में हूं कि पावरशेल आधिकारिक ट्यूटोरियल के साथ क्यों नहीं आता है। यह भाषा युक्ति वैसी ही दिखती है जैसी मैं देख रहा हूं। एक बार फिर धन्यवाद!
रायलूओ

256

किसी ने भी सिंगल और डबल कोट्स के बीच अंतर का उल्लेख नहीं किया है। (मैं 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

( http://ss64.com/ps/syntax-esc.html मुझे संदर्भ के लिए अच्छा लगता है)।


1
1.0 के साथ भी काम करता है।
स्मित जॉन्थ

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
मुझे नहीं लगता है कि पिछले एक ठीक उसी तरह काम करता है जैसा आप उम्मीद करेंगे यहां पास्टबिन देखें । Powershell एक (भले ही आपके पास यहां दो हैं) $assoc.Idऔर "(एट अल) के बीच व्हाट्सएप के आउटपुट के लिए स्थान जोड़ देगा । यही है, विकल्प 1 आपको Id__-__Name__-__Owner(प्रत्येक के प्रत्येक तरफ दो स्थान -) देता है, लेकिन विकल्प 3 देता है Id___-___Name___-___Owner( तीन स्थान)।
रफिन

4
शायद एक अधिक उपयोगी pastebin । ### के दोनों ओर रिक्त स्थान जोड़ $assoc.Id"###"$assoc.Name देगा , जहां "$($assoc.Id)###$($assoc.Name)" नहीं होगा
रफिन

1
दूसरे ने मुझे विश्वास दिलाया कि मुझे अपने उद्देश्यों की आवश्यकता है - धन्यवाद!
MaVCArt

123

आप भी उपयोग कर सकते हैं -join

उदाहरण के लिए

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

$ नाम के लिए "जॉन" असाइन करेगा।

इसलिए आउटपुट के लिए, एक लाइन में:

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

हां, यह स्ट्रिंग कॉन्सेप्टन है। इसमें नए लिंक या अतिरिक्त स्थान नहीं जोड़े गए हैं। यह आपको सिंगल या डबल-उद्धृत स्ट्रिंग्स का उपयोग करने देता है।
लेक्सीहिन्स

यह ट्रिक सच कॉन्सेटेशन है और आपको मल्टी लाइन स्ट्रिंग्स करने की अनुमति देता है, जैसे कि आप .net। मल्टीलाइन SQL स्टेटमेंट करने के लिए बहुत अच्छा है! क्यों शक्तियां डिफ़ॉल्ट रूप से ऐसा नहीं करती हैं !?
ब्रेन

करने के कई तरीके हैं। लेकिन यह स्ट्रिंग संघनन का सही उत्तर है।
chingNotCHing

32

एक अन्य विकल्प है:

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

"सर्वोत्तम" विधि संभवतः एक सीबी है जो सुझाया गया है:

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

3
StringBuilderयदि आप कॉन्कैट-क्रेजी हो रहे हैं तो आपको विकल्प जोड़ने की आवश्यकता है । ; ^)
रफिन

2
निश्चित रूप से वांछित गुणों को एक बाहरी फ़ाइल में पाइप करने का एक तरीका है, फिर उन्हें एफेन (!) के साथ जुड़े घटकों की एक स्ट्रिंग में deserialize करें
कोड जॉकी

यह मुश्किल से एक aproach की कल्पना करना मुश्किल है। स्ट्रिंग्स अपरिवर्तनीय हैं, इसलिए प्रत्येक कॉन्फैक्शन ऑपरेशन वास्तव में मूल के वर्णों की नकल करते हुए एक नया स्ट्रिंग पैदा करता है।
1

22

Cmdlet में विभिन्न मापदंडों के रूप में व्यवहार किए जाने से रोकने के लिए आपको कोष्ठक में अभिव्यक्ति देने की आवश्यकता है:

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

यह लिखें-डीबग के लिए अनिवार्य है
फ्रैंक

19

जबकि अभिव्यक्ति:

"string1" + "string2" + "string3"

तार को समाप्‍त कर देगा। पॉवरशेल कमांड में पास होने पर आपको एकल तर्क के रूप में मूल्यांकन करने के लिए कोष्ठक के सामने $ डालने की आवश्यकता होती है। उदाहरण:

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

एक बोनस के रूप में, यदि आप चाहते हैं कि यह कई लाइनों को फैलाए, तो आपको लाइन के अंत में बैकवर्ड के दाईं ओर (किसी भी स्थान या वर्ण के बिना) बैकवर्ड सिंटैक्स का उपयोग करने की आवश्यकता है। उदाहरण:

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

(वास्तव में, मुझे लगता है कि वर्तमान में Powershell को थोड़ा गलत तरीके से लागू किया गया है, कोष्ठक के बीच अनावश्यक बैक-टिक की आवश्यकता होती है। यदि Microsoft बस "पायथन" या "TCL" कोष्ठक का पालन करेगा, तो आपको शुरू करने और दोनों के बीच जितनी नई रूपरेखाएँ डालने की अनुमति होगी, उतने ही नए नियम बनाएंगे। कोष्ठक को समाप्त करने के बाद वे अधिकांश समस्याओं को हल करेंगे जो लोगों को लाइन निरंतरता से संबंधित शक्तियों के बारे में पसंद नहीं है, और स्ट्रिंग्स के संयोजन से मैंने यह पाया है कि आप कोष्ठक के बीच लाइन निरंतरता पर कभी-कभी बैक-टिक को छोड़ सकते हैं, लेकिन इसके वास्तव में परतदार और अनपेक्षित अगर यह काम करेगा .. इसका बेहतर सिर्फ बैकटिक्स जोड़ना है।)



9

मैं सिर्फ .NET String.Format का उपयोग करके ऐसा करने के लिए एक और तरीका लाना चाहता हूं :

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

2
String.Formatपुराने सादे के बजाय .NET का उपयोग करने का कोई फायदा है "{0}" -f $var? मैं .NET कोड का उपयोग करने में वह बिंदु नहीं देखता जहाँ प्लेन
पावरशेल

4
@DineiRockenbach शायद नहीं। बस एक और उदाहरण सामने लाना चाहता था।
मार्टिन ब्रैंडल

9

(वर्तमान पीएस संस्करण 5.1.17134.407)

यह सब कहा गया है और अब तक मुझे लगता है लेकिन यह भी अब के रूप में काम करता है:

$myVar = "Hello"

echo "${myVar} World"

नोट: यह केवल दोहरे उद्धरण चिह्नों के साथ काम करता है


7

ये जवाब बहुत जटिल लगते हैं। यदि आप इसे PowerShell स्क्रिप्ट में उपयोग कर रहे हैं, तो आप बस ऐसा कर सकते हैं:

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

इसका उत्पादन होगा

मेरा नाम स्लिम छायादार है

ध्यान दें कि आपके लिए शब्दों के बीच एक स्थान कैसे रखा गया है



6

कॉनसेटनेट स्ट्रिंग्स ठीक वैसे ही जैसे डॉस दिनों में। यह लॉगिंग के लिए एक बड़ी बात है ताकि आप यहां जाएं:

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

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

6

मैं इसके साथ (और कई अन्य अनजानी चीजों के साथ) संघर्ष कर रहा हूं, हर बार जब मैं पावरशेल का उपयोग करता हूं तो इससे दूर हो जाता हूं, इसलिए मैं अब इसका विकल्प चुनता हूं:

[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 " - "

लेकिन अगर आप यह निर्दिष्ट नहीं करते हैं कि ऑब्जेक्ट को आदेश दिया जाना चाहिए, तो पॉवर्सशेल एक यादृच्छिक क्रम में मूल्यों को प्रदर्शित करेगा। इसलिए झंडा जोड़ना चाहिए [आदेश दिया]

$assoc = [pscustomobject] [ordered] @{
    Id = 42
    Name = "Slim Shady"
    Owner = "Eminem"
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.