मैं PowerShell में एक नई पंक्ति के बिना टेक्स्ट कैसे आउटपुट करूं?


145

मैं अपनी पॉवरशेल स्क्रिप्ट को कुछ इस तरह प्रिंट करना चाहता हूं:

Enabling feature XYZ......Done

स्क्रिप्ट कुछ इस तरह दिखती है:

Write-Output "Enabling feature XYZ......."
Enable-SPFeature...
Write-Output "Done"

लेकिन Write-Outputहमेशा एक नई लाइन को अंत में प्रिंट करता है ताकि मेरा आउटपुट एक लाइन पर न हो। क्या इसे करने का कोई तरीका है?


जवाबों:


165

लिखें-होस्ट -NoNewline "सक्षम करने की सुविधा XYZ ......."


62
डाउनवोटेड क्योंकि ओपी का उदाहरण विशेष रूप से उपयोग करता है Write-Output, जिसकी तुलना में अलग-अलग फ़ंक्शन हैं Write-Host। उत्तर को कॉपी / पेस्ट करने से पहले पाठकों को इस बड़ी विसंगति पर ध्यान देना चाहिए।
नाथनअल्डनसेर

5
मैं @NathanAldenSr के साथ सहमत हूं, अगर आप किसी फ़ाइल आदि के लिए आउटपुट करने का प्रयास कर रहे हैं, तो राइट-होस्ट मदद नहीं करता है
स्टीवंथ्रेड

6
Write-Hostलगभग सही उत्तर नहीं है। यह >/dev/ttyयूनिक्सलैंड में करने के बराबर है ।
मार्क रीड

2
Write-Progressकुछ मामलों में उपयुक्त हो सकता है, नीचे उदाहरण देखें।
थॉमस

12
नीचे दिया गया क्योंकि ओपी का उदाहरण विशेष रूप से उपयोग करता है Write-Output। पैरामीटर Write-Outputनहीं है -NoNewLine
Slogmeister Extraordinaire

49

दुर्भाग्य से, जैसा कि कई उत्तरों और टिप्पणियों में उल्लेख किया गया है, Write-Hostखतरनाक हो सकता है और अन्य प्रक्रियाओं के लिए पाइप नहीं किया जा सकता है और ध्वज Write-Outputनहीं है -NoNewline

लेकिन उन तरीकों "* NIX" प्रदर्शन प्रगति के लिए तरीके हैं, "PowerShell" तरीका है कि ऐसा करने के लिए हो रहा है Write-Progress: यह प्रगति की जानकारी के साथ PowerShell विंडो के शीर्ष पर एक बार, PowerShell 3.0 से ले कर उपलब्ध प्रदर्शित करता है, मैनुअल देखें के लिए विवरण।

# Total time to sleep
$start_sleep = 120

# Time to sleep between each notification
$sleep_iteration = 30

Write-Output ( "Sleeping {0} seconds ... " -f ($start_sleep) )
for ($i=1 ; $i -le ([int]$start_sleep/$sleep_iteration) ; $i++) {
    Start-Sleep -Seconds $sleep_iteration
    Write-Progress -CurrentOperation ("Sleep {0}s" -f ($start_sleep)) ( " {0}s ..." -f ($i*$sleep_iteration) )
}
Write-Progress -CurrentOperation ("Sleep {0}s" -f ($start_sleep)) -Completed "Done waiting for X to finish"

और ओपी का उदाहरण लेने के लिए:

# For the file log
Write-Output "Enabling feature XYZ"

# For the operator
Write-Progress -CurrentOperation "EnablingFeatureXYZ" ( "Enabling feature XYZ ... " )

Enable-SPFeature...

# For the operator
Write-Progress -CurrentOperation "EnablingFeatureXYZ" ( "Enabling feature XYZ ... Done" )

# For the log file
Write-Output "Feature XYZ enabled"

3
मुझे लगता है कि यह स्थिति दिखाने के लिए सबसे अच्छा समाधान है। यदि आपको लॉग-इन करने की आवश्यकता है या कुछ लिखना है, तो आपको राइट-आउटपुट के लाइनब्रेक के साथ जीवन जीना होगा।
फादनर

1
सहमत, प्लस डिस्प्ले का बिंदु "लाइव होने के लिए फैंसी" होना है, लॉग फाइल में इसे रखने का कोई मतलब नहीं है: प्रिंट "कुछ करना शुरू करें" फिर "कुछ किया"
थॉमस

13

हालांकि यह आपके मामले में काम नहीं कर सकता है (चूंकि आप उपयोगकर्ता को सूचनात्मक आउटपुट प्रदान कर रहे हैं), एक स्ट्रिंग बनाएं जो आप आउटपुट को जोड़ने के लिए उपयोग कर सकते हैं। जब इसे आउटपुट करने का समय आता है, तो बस स्ट्रिंग को आउटपुट करें।

इस उदाहरण की उपेक्षा करना कि यह उदाहरण आपके मामले में मूर्खतापूर्ण है लेकिन अवधारणा में उपयोगी है:

$output = "Enabling feature XYZ......."
Enable-SPFeature...
$output += "Done"
Write-Output $output

प्रदर्शित करता है:

Enabling feature XYZ.......Done

1
यह प्रदान किए गए विशिष्ट उदाहरण में काम कर सकता है, लेकिन अभी भी एक अतिरिक्त लाइन फीड का उत्पादन होता है Write-Output। उचित समाधान, लेकिन समाधान नहीं।
Slogmeister Extraordinaire

राइट-आउटपुट हमेशा अंत में एक नई पंक्ति आउटपुट करता है। वहाँ कोई रास्ता नहीं है कि इस cmdlet के साथ
shufler

7
सुविधा स्थापित होने के बाद संपूर्ण आउटपुट प्रकट होने के बाद से यह बिंदु नहीं है।
मेजकिनटोर

10
मुझे समझ में नहीं आता है, जो इस सवाल पर 1 से अधिक अपवित्र देता है, क्योंकि यह बात नहीं है क्योंकि पूरे आउटपुट के बाद यह प्रतीत होता है कि सुविधा स्थापित है
अधिकतम 18:15

1
"इस बात की अनदेखी कि यह उदाहरण आपके मामले में मूर्खतापूर्ण है, लेकिन अवधारणा में उपयोगी है:"
शफलर

6

हां, जैसा कि अन्य उत्तरों में कहा गया है, यह राइट-आउटपुट के साथ नहीं किया जा सकता है। जहाँ PowerShell विफल हो जाता है, .NET पर जाएँ, यहाँ भी .NET उत्तरों के एक जोड़े हैं, लेकिन वे होने की तुलना में अधिक जटिल हैं।

महज प्रयोग करें:

[Console]::Write("Enabling feature XYZ.......")
Enable-SPFeature...
Write-Output "Done"

यह शुद्धतम पॉवरशेल नहीं है, लेकिन यह काम करता है।


5
नीचा दिखाया गया है क्योंकि यह ऐसा व्यवहार करता है Write-Host, सिवाय इसके कि लोग इसकी उम्मीद नहीं करेंगे।
जेबर्ट

4

किसी फ़ाइल पर लिखने के लिए आप बाइट सरणी का उपयोग कर सकते हैं। निम्न उदाहरण एक खाली ज़िप फ़ाइल बनाता है, जिसे आप निम्न फ़ाइलों में जोड़ सकते हैं:

[Byte[]] $zipHeader = 80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
[System.IO.File]::WriteAllBytes("C:\My.zip", $zipHeader)

या उपयोग करें:

[Byte[]] $text = [System.Text.Encoding]::UTF8.getBytes("Enabling feature XYZ.......")
[System.IO.File]::WriteAllBytes("C:\My.zip", $text)

यह एक बहुत बढ़िया उदाहरण है!
पीटर मोर्टेंसन

2

FrinkTheBrave की प्रतिक्रिया के लिए एक सरलीकरण:

[System.IO.File]::WriteAllText("c:\temp\myFile.txt", $myContent)

इस सवाल का जवाब बिल्कुल नहीं है।
नाथनअल्डनसेर

2
लेकिन यह ठीक है कि मैंने क्या खोजा था और मुझे सवाल के शीर्षक से क्या उम्मीद थी।
पैट्रिक रॉक्स

2

समस्या यह है कि मैं लिख रहा था कि राइट-आउटपुट वास्तव में पॉवरशेल वी 2 का उपयोग करते समय आउटपुट को कम से कम स्ट्रैडआउट करने के लिए उपयोग करता है। मैं सफलता के बिना पीछा करने के लिए एक्सएमएल पाठ लिखने की कोशिश कर रहा था, क्योंकि यह चरित्र 80 पर लिपटा मुश्किल होगा।

वर्कअराउंड का उपयोग करना था

[Console]::Out.Write($myVeryLongXMLTextBlobLine)

यह PowerShell v3 में कोई समस्या नहीं थी। लगता है कि आउटपुट वहां ठीक से काम कर रहा है।

PowerShell स्क्रिप्ट को कैसे लागू किया जाता है, इसके आधार पर, आपको उपयोग करने की आवश्यकता हो सकती है

[Console]::BufferWidth =< length of string, e.g. 10000)

इससे पहले कि आप stdout को लिखें।


2
राइट-होस्ट की तरह व्यवहार करता है, लेकिन सबसे खराब। आप इसे उदाहरण के लिए फ़ाइल करने के लिए पाइप नहीं कर सकते।
मेजकिनटोर

2

ऐसा लगता है कि PowerShell में ऐसा करने का कोई तरीका नहीं है। पिछले सभी उत्तर सही नहीं हैं, क्योंकि वे व्यवहार करने का तरीका नहीं बताते हैं, Write-Outputलेकिन अधिक पसंद करते हैं, जिस Write-Hostपर वैसे भी यह समस्या नहीं है।

क्लोजर समाधान पैरामीटर के Write-Hostसाथ उपयोग करने लगता है -NoNewLine। आप इसे पाइप नहीं कर सकते हैं जो आम तौर पर एक समस्या है, लेकिन इस फ़ंक्शन को ओवरराइड करने का एक तरीका है जैसा कि राइट-होस्ट => फ़ाइल में निर्यात करें , ताकि आप इसे आसानी से आउटपुट फ़ाइल के लिए पैरामीटर स्वीकार कर सकें। यह अभी भी एक अच्छे समाधान से दूर है। इसके साथ Start-Transcriptयह अधिक प्रयोग करने योग्य है, लेकिन उस cmdlet में मूल अनुप्रयोगों की समस्याएं हैं।

Write-Outputबस एक सामान्य संदर्भ में आपको वह नहीं करना चाहिए जो आपको चाहिए।


2

Write-Hostभयानक है, दुनिया का एक विध्वंसक, फिर भी आप इसका उपयोग केवल Write-Outputलॉग का उपयोग करते हुए उपयोगकर्ता को प्रगति प्रदर्शित करने के लिए कर सकते हैं (ऐसा नहीं है कि ओपी ने लॉगिंग के लिए कहा हो)।

Write-Output "Enabling feature XYZ" | Out-File "log.txt" # Pipe to log file
Write-Host -NoNewLine "Enabling feature XYZ......."
$result = Enable-SPFeature
$result | Out-File "log.txt"
# You could try{}catch{} an exception on Enable-SPFeature depending on what it's doing
if ($result -ne $null) {
    Write-Host "complete"
} else {
    Write-Host "failed"
}

प्रगति का संकेत देने के लिए आपकी आवश्यकताओं पर निर्भर करता है, वहाँ भी है Write-Progress
चावर

1

आप बस उन pesky newlines को छोड़ने के लिए PowerShell प्राप्त नहीं कर सकते ... कोई स्क्रिप्ट या cmdlet नहीं है जो करता है। बेशक, लिखें-मेजबान पूर्ण बकवास है, क्योंकि आप इससे अनुप्रेषित / पाइप नहीं कर सकते हैं!

फिर भी, आप इसे करने के लिए अपनी खुद की EXE फाइल लिख सकते हैं, जो कि मैंने स्टैक ओवरफ्लो प्रश्न में कैसे किया जाए यह बताया कि पावरशेल में कुछ आउटपुट कैसे करें


2
गलत जानकारी। जैसा कि शाय और जे ने उत्कृष्ट रूप से उत्तर दिया, बस पहले तर्क के रूप में -NoNewline जोड़ें।
डेविड हॉटस्पॉट ऑफिस में

2
शायद यह मामला अब @DavidatHotspotOffice है, लेकिन जब मैंने आखिरी बार एक विंडोज़ बॉक्स (एक साल पहले) को छुआ था जो काम नहीं करता था, तो आप लिखो-होस्ट से पुनर्निर्देशित / पाइप नहीं कर सकते थे। निष्पक्ष होने के लिए मेरे पास POSH या .NET के लिए थोड़ी सी भी धैर्य नहीं था, मैंने कुछ महीनों के बाद छोड़ दिया और वापस यूनिक्स भूमि पर चला गया। मजाकिया
samthebest

3
@DavidatHotspotOffice - वास्तव में, वह सही है। राइट-आउटपुट के लिए कोई "NoNewLine" तर्क नहीं है, जो कि मूल प्रश्न के बारे में पूछ रहा था। राइट-आउटपुट का उपयोग करने के लिए कुछ अच्छे कारण हैं, ऐसा लगता है - इसलिए यह उत्तर समझ में आता है। jsnover.com/blog/2013/12/07/write-host-considered-harmful
जेम्स रस्किन

डाउनवोट किया गया क्योंकि सवाल "पॉवरशेल" में एक समाधान के लिए पूछ रहा है। बाहरी EXE लिखना "इन पॉवरशेल" नहीं है।
Slogmeister Extraordinaire

1
@SlogmeisterExtraordinaire यह PowerShell में संभव नहीं है इसलिए मेरा उत्तर उचित है। आपका सिर्फ अपमानजनक है क्योंकि आपका इतना दुखी है कि आपको दुनिया के सबसे बुरे ऑपरेटिंग सिस्टम के साथ काम करना पड़ता है जिसमें दुनिया के सबसे खराब खोल हैं।
samthebest

1

शफलर द्वारा उत्तर सही है। एक और तरीका बताया: ARRAY FORM का उपयोग करके राइट-आउटपुट में मानों को पास करने के बजाय,

Write-Output "Parameters are:" $Year $Month $Day

लिखने-आउटपुट के लिए कई कॉल के बराबर या,

Write-Output "Parameters are:"
Write-Output $Year
Write-Output $Month
Write-Output $Day
Write-Output "Done."

अपने घटकों को एक STRING VARIABLE में पहले:

$msg="Parameters are: $Year $Month $Day"
Write-Output $msg

यह लिखावट-आउटपुट को कई बार (या ARRAY FORM) के कारण होने वाले मध्यवर्ती CRLF को रोक देगा, लेकिन निश्चित रूप से लिख-आउटपुट कमांडलेट के अंतिम CRLF को दबाएगा नहीं। उसके लिए, आपको अपना खुद का कमांडलेट लिखना होगा, यहां सूचीबद्ध अन्य जटिल वर्कअराउंड में से एक का उपयोग करें, या तब तक प्रतीक्षा करें जब तक कि Microsoft समर्थन करने का निर्णय नहीं लेता।-NoNewline राइट-आउटपुट विकल्प ।

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


मैं दूसरों पर इस जवाब को पसंद करता हूं। यदि आप वस्तुओं के गुणों को बुला रहे हैं, तो आप उन्हें उद्धरणों में संलग्न नहीं कर सकते हैं इसलिए मैंने उपयोग किया: लिखो-आउटपुट ($ msg = $ MyObject.property + "कुछ पाठ जिन्हें मैं शामिल करना चाहता हूं" + $ Object.property)
लुईस

2
@ लुईस आप निश्चित रूप से एक स्ट्रिंग के अंदर ऑब्जेक्ट गुण शामिल कर सकते हैं! किसी भी चर को घेरने के लिए $ () अभिव्यक्ति का उपयोग करें, जैसे "$ ($ MyObject.Property) कुछ पाठ मैं $ ($ Object.property) को शामिल करना चाहता हूं"
shufler

यह प्रदान किए गए विशिष्ट उदाहरण में काम कर सकता है, लेकिन अभी भी एक अतिरिक्त लाइन फीड है Write-Output, जिसके द्वारा आप इसे देख नहीं सकते हैं क्योंकि यह अंतिम चीज़ है। उचित समाधान, लेकिन समाधान नहीं। परिणामी आउटपुट का उपभोग करने वाली कोई चीज हो सकती है जो अनुगामी न्यूलाइन को संभाल नहीं सकती है।
Slogmeister Extraordinaire

1
गलत। समाधान एक आदेश के साथ नहीं किया जा सकता है।
मेजकिनटोर

यह प्रश्न को संबोधित नहीं करता है। लॉग फ़ाइल आउटपुट को उस ऑपरेशन को दिखाना चाहिए जो प्रयास करने वाला था ताकि विफलता को देखा जा सके और उसका पता लगाया जा सके। वैराग्य वह हासिल नहीं करता है।
ड्यूरेट्टे

0

निम्नलिखित पिछली पंक्ति की शुरुआत में कर्सर को वापस रखेगा। यह आपको सही क्षैतिज स्थिति में रखना है (बग़ल में ले जाने के लिए $ pos.X का उपयोग करना):

$pos = $host.ui.RawUI.get_cursorPosition()
$pos.Y -= 1
$host.UI.RawUI.set_cursorPosition($Pos)

आपका वर्तमान आउटपुट 27 स्थान पर है, इसलिए $ pos.X = 27 काम कर सकता है।


इसका फ़ाइल आउटपुट से कोई लेना-देना नहीं है।
Slogmeister Extraordinaire

यह भी बुरा नहीं है। यदि आप $pos.Xभी करते हैं तो यह सही उत्पादन कर सकता है । समस्या यह है कि यदि आप इसे एक फ़ाइल पर पाइप करते हैं, तो दो अलग-अलग लाइनें दिखाई देती हैं।
मेजकिनटोर

0

यह बहुत सुरुचिपूर्ण नहीं हो सकता है, लेकिन यह वही करता है जो ओपी ने अनुरोध किया था। ध्यान दें कि ISE StdOut के साथ गड़बड़ करता है, इसलिए कोई आउटपुट नहीं होगा। इस स्क्रिप्ट के काम को देखने के लिए इसे ISE के भीतर नहीं चलाया जा सकता है।

$stdout=[System.Console]::OpenStandardOutput()
$strOutput="Enabling feature XYZ... "
$stdout.Write(([System.Text.Encoding]::ASCII.GetBytes($strOutput)),0,$strOutput.Length)
Enable-SPFeature...
$strOutput="Done"
$stdout.Write(([System.Text.Encoding]::ASCII.GetBytes($strOutput)),0,$strOutput.Length)
$stdout.Close()

1
गलत। यदि आप इसे किसी फ़ाइल में डालते हैं और इसका आउटपुट कुछ भी नहीं होता है।
मेजकिनटोर

एक फ़ाइल के लिए पाइपिंग कुछ ऐसा नहीं था जिसे ओपी ने अनुरोध किया था। और हाँ, [System.Console]एक फ़ाइल पर पुनर्निर्देशित नहीं किया जा सकता है।
स्लोगमिस्टर एक्स्ट्राऑर्डिनेयर

0

मैंने धोखा दिया, लेकिन मेरा मानना ​​है कि यह एकमात्र उत्तर है जो हर आवश्यकता को संबोधित करता है। अर्थात्, यह अनुगामी CRLF से बचा जाता है, इस बीच अन्य ऑपरेशन को पूरा करने के लिए एक जगह प्रदान करता है, और आवश्यक रूप से stdout करने के लिए ठीक से रीडायरेक्ट करता है।

$c_sharp_source = @"
using System;
namespace StackOverflow
{
   public class ConsoleOut
   {
      public static void Main(string[] args)
      {
         Console.Write(args[0]);
      }
   }
}
"@
$compiler_parameters = New-Object System.CodeDom.Compiler.CompilerParameters
$compiler_parameters.GenerateExecutable = $true
$compiler_parameters.OutputAssembly = "consoleout.exe"
Add-Type -TypeDefinition $c_sharp_source -Language CSharp -CompilerParameters $compiler_parameters

.\consoleout.exe "Enabling feature XYZ......."
Write-Output 'Done.'

0
$host.UI.Write('Enabling feature XYZ.......')
Enable-SPFeature...
$host.UI.WriteLine('Done')

0

वांछित ओ / पी: सक्षम सुविधा XYZ ...... हो गया

आप नीचे कमांड का उपयोग कर सकते हैं

$ a = "सुविधा XYZ सक्षम करना"

लिखो-आउटपुट "$ एक ...... हो गया"

आपको उद्धरण चिह्नों के अंदर चर और कथन जोड़ना होगा। उम्मीद है कि यह उपयोगी है :)

धन्यवाद Techiegal


आउट-आउटपुट को पाइपलाइन से बाहर की वस्तुओं को डालने के लिए पसंद किया जाता है। पाठ प्रदर्शन के लिए, राइट-होस्ट का उपयोग अक्सर किया जाता है और हाल ही में सूचना-स्ट्रीम पर लिखने के लिए राइट-इनफॉर्मेशन का उपयोग किया जाता है।
लॉजिकलडाग्राम

0

यहाँ पहले से ही बहुत जवाब है, कोई भी यहाँ नीचे स्क्रॉल नहीं करेगा। वैसे भी निम्नलिखित के साथ अंत में एक नई पंक्ति के बिना पाठ लिखने का एक समाधान भी है:

एन्कोडिंग के साथ फ़ाइल आउटपुट:

  # a simple one liner
  "Hello World, in one line" | Out-File -Append -Encoding ascii -NoNewline -FilePath my_file.txt;

  # this is a test to show how it works
  "Hello World".Split(" ") | % { "_ $_ _" | Out-File -Append -Encoding ascii -NoNewline -FilePath my_file.txt; }

सांत्वना उत्पादन:

  # a simple one liner
  "Hello World, in one line" | Write-Host -NoNewline;

  # this is a test to show how it works
  "Hello World".Split(" ") | % { "_ $_ _" | Write-Host -NoNewline; }

-3

आप बिल्कुल ऐसा कर सकते हैं। राइट-आउटपुट में " NoEnumerate " नामक एक ध्वज है जो अनिवार्य रूप से एक ही चीज़ है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.