Windows-batch: ekko uden ny linje

Indlæg af Hanne Mølgaard Plasc

Problem



Hvad er Windows-batchet ækvivalent med Linux Shell-kommandoen echo -n, som undertrykker Newline i slutningen af ​​output?


Tanken er at skrive på samme linje i en loop.

Bedste reference


Ved hjælp af set og /p parameteren kan du echo uden newline:


C:> echo Hello World
Hello World

C:> echo|set /p="Hello World"
Hello World
C:>


Kilde [46]

Andre referencer 1


Brug af: echo | set /p= eller <NUL set /p= vil begge arbejde for at undertrykke newline.


Dette kan dog være meget farligt, når du skriver mere avancerede scripts, når du kontrollerer ERRORLEVEL bliver vigtigt som indstilling set /p= uden at angive et variabelnavn, indstiller ERRORLEVEL til 1.


En bedre tilgang ville være at bare bruge et dummy variabelnavn som sådan:


echo | set /p dummyName=Hello World


Dette vil producere præcis, hvad du vil, uden at nogen snigende ting foregår i baggrunden, da jeg var nødt til at finde ud af den hårde måde, men det virker kun med piped-versionen; <NUL set /p dummyName=Hello vil stadig hæve ERRORLEVEL til 1.

Andre referencer 2


Den simple SET/P-metode har begrænsninger, der varierer lidt mellem Windows-versioner.



  • Ledende citater kan fjernes

  • Ledende hvidt mellemrum kan fjernes

  • Ledende = forårsager en syntaksfejl.



Se http://www.dostips.com/forum/viewtopic.php?f=3u0026amp;t=4209 for mere information. [47]


jeb skrev en klog løsning, der løser de fleste af problemerne ved Output-tekst uden linefeed, selv med ledende plads eller=Jeg har raffineret metoden, så det trygt kan udskrive helt enhver gyldig batchstreng uden den nye linje på enhver version af Windows fra XP og fremover. Bemærk at :writeInitialize -metoden indeholder en streng bogstavlig, der muligvis ikke poster godt til webstedet. Der er en bemærkning, der beskriver, hvad tegnsekvensen skal være. [48]


Metoden :write og :writeVar er optimeret således, at kun strenge indeholdende besværlige hovedpersoner er skrevet ved hjælp af min ændrede version af jebs COPY-metode. Ikke-besværlige strenge er skrevet ved hjælp af den enklere og hurtigere SET/P metode.


@echo off
setlocal disableDelayedExpansion
call :writeInitialize
call :write "=hello"
call :write " world!\%$write.sub\%OK!"
echo(
setlocal enableDelayedExpansion
set lf=^


set "str= hello!lf!world^!!!$write.sub!hello!lf!world"
echo(
echo str=!str!
echo(
call :write "str="
call :writeVar str
echo(
exit /b

:write  Str
::
:: Write the literal string Str to stdout without a terminating
:: carriage return or line feed. Enclosing quotes are stripped.
::
:: This routine works by calling :writeVar
::
setlocal disableDelayedExpansion
set "str=\%~1"
call :writeVar str
exit /b


:writeVar  StrVar
::
:: Writes the value of variable StrVar to stdout without a terminating
:: carriage return or line feed.
::
:: The routine relies on variables defined by :writeInitialize. If the
:: variables are not yet defined, then it calls :writeInitialize to
:: temporarily define them. Performance can be improved by explicitly
:: calling :writeInitialize once before the first call to :writeVar
::
if not defined \%~1 exit /b
setlocal enableDelayedExpansion
if not defined $write.sub call :writeInitialize
set $write.special=1
if "!\%~1:~0,1!" equ "^!" set "$write.special="
for /f delims^=^ eol^= \%\%A in ("!\%~1:~0,1!") do (
  if "\%\%A" neq "=" if "!$write.problemChars:\%\%A=!" equ "!$write.problemChars!" set "$write.special="
)
if not defined $write.special (
  <nul set /p "=!\%~1!"
  exit /b
)
>"\%$write.temp\%\_1.txt" (echo !str!!$write.sub!)
copy "\%$write.temp\%\_1.txt" /a "\%$write.temp\%\_2.txt" /b >nul
type "\%$write.temp\%\_2.txt"
del "\%$write.temp\%\_1.txt" "\%$write.temp\%\_2.txt"
set "str2=!str:*\%$write.sub\%=\%$write.sub\%!"
if "!str2!" neq "!str!" <nul set /p "=!str2!"
exit /b


:writeInitialize
::
:: Defines 3 variables needed by the :write and :writeVar routines
::
::   $write.temp - specifies a base path for temporary files
::
::   $write.sub  - contains the SUB character, also known as <CTRL-Z> or 0x1A
::
::   $write.problemChars - list of characters that cause problems for SET /P
::      <carriageReturn> <formFeed> <space> <tab> <0xFF> <equal> <quote>
::      Note that <lineFeed> and <equal> also causes problems, but are handled elsewhere
::
set "$write.temp=\%temp\%writeTemp\%random\%"
copy nul "\%$write.temp\%.txt" /a >nul
for /f "usebackq" \%\%A in ("\%$write.temp\%.txt") do set "$write.sub=\%\%A"
del "\%$write.temp\%.txt"
for /f \%\%A in ('copy /z "\%~f0" nul') do for /f \%\%B in ('cls') do (
  set "$write.problemChars=\%\%A\%\%B    ""
  REM the characters after \%\%B above should be <space> <tab> <0xFF>
)
exit /b

Andre referencer 3


En løsning til det strippede hvide rum i SET/P:


Tricket er den backspace char, som du kan kalde i teksteditoren EDIT til DOS. For at oprette det i EDIT, tryk på ctrlP + ctrlH .
Jeg vil indsætte det her, men denne webside kan ikke vise den. Den er synlig på Notepad selv (den er som et lille sort rektangel med en hvid cirkel i midten)


Så skriver du dette:


<nul set /p=.9    Hello everyone


Punten kan være en char, det er kun der for at fortælle SET/P, at teksten starter der, før mellemrummet og ikke på ' Hej '.
' 9 ' er en gengivelse af backspace char, som jeg ikke kan vise her. Du skal sætte den i stedet for 9, og den vil slette . ', hvorefter du får det her:


    Hello Everyone


i stedet for:


Hello Everyone


Jeg håber det hjælper

Andre referencer 4


Du kan fjerne newline ved hjælp af 'tr' fra gnuwin32 (coreutils pakke) [49]


@echo off
set L=First line
echo \%L\% | tr -d "
"
echo Second line
pause


Forresten, hvis du laver masser af scripting, er gnuwin32 en guldminde.

Andre referencer 5


Som et tillæg til @xmechanixs svar bemærkede jeg ved at skrive indholdet til en fil:


echo | set /p dummyName=Hello World > somefile.txt


At dette vil tilføje et ekstra mellemrum i slutningen af ​​den udskrevne streng , hvilket kan være ubelejligt, især da vi forsøger at undgå at tilføje en ny linje (et andet mellemrumstegn) til slutningen af ​​strengen .


Heldigvis citerer strengen, der skal udskrives, dvs. ved at bruge:


echo | set /p dummyName="Hello World" > somefile.txt


Vil udskrive strengen uden noget nyt eller mellemrum tegn i slutningen.

Andre referencer 6


Her er en anden metode, den bruger Powershell Write-Host, som har en -NoNewLine-parameter, kombinerer den med start /b og den tilbyder den samme funktionalitet fra batch.


NoNewLines.cmd


@ECHO OFF
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 1 - ';Write-Host -NoNewLine 'Result 2 - ';Write-Host -NoNewLine 'Result 3 - '"
PAUSE


Produktion


Result 1 - Result 2 - Result 3 - Press any key to continue . . .


Denne nedenfor er lidt anderledes, fungerer ikke nøjagtigt som OP ønsker, men er interessant, fordi hvert resultat overskriver det tidligere resultat, der emulerer en tæller.


@ECHO OFF
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 1 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 2 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 3 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 4 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 5 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 6 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 7 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 8 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 9 - '"
PAUSE

Andre referencer 7


Måske er det det du leder efter, det er et gammelt skole script ...: P


set nl=^& echo. 
echo \%nl\%The\%nl\%new\%nl\%line\%nl\%is\%nl\%not\%nl\%apparent\%nl\%throughout\%nl\%text\%nl\%
echo only in prompt.
pause


eller måske forsøger du at erstatte en nuværende linje i stedet for at skrive til en ny linje?
Du kan eksperimentere med dette ved at fjerne '\% bs\%' efter '.' underskrive og også ved at uddele den anden '\% bs\%' efter 'Eksempelbesked'.


for /f \%\%a in ('"prompt $H&for \%\%b in (1) do rem"') do set "bs=\%\%a"
<nul set /p=.\%bs\%         Example message         \%bs\%
pause


Jeg finder dette virkelig interessant, fordi det bruger en variabel til et andet formål end hvad det er meningen at gøre. som du kan se, '\% bs\%' repræsenterer et backspace. Den anden '\% bs\%' bruger backspace til at tilføje mellemrum efter 'Eksempelbesked' for at adskille udgangen 'Pause-kommando' s uden at tilføje et synligt tegn efter 'Eksempelbesked'. Det er dog også muligt med en almindeligt procenttegn.

Andre referencer 8



  Herfra



<nul set /p =Testing testing


og også at ekko begynder med mellemrum brug


echo.Message goes here

Andre referencer 9


DIY cw.exe (konsolskriv) hjælpeprogram



Hvis du ikke finder det ude af hylderne, kan du gøre det selv. Med dette cw værktøj kan du bruge alle slags tegn. I det mindste vil jeg gerne tænke så. Vær venlig at stress-test det og lad mig vide.


Værktøjer



Alt du behøver er .NET installeret, hvilket er meget almindeligt i dag. [51]


Materialer



Nogle tegn skrevet/kopieret-indsat.


Steps




  1. Opret .bat fil med følgende indhold.





/* >nul 2>&1

@echo off
setlocal

set exe=cw
for /f "tokens=* delims=" \%\%v in ('dir /b /s /a:-d  /o:-n "\%SystemRoot\%Microsoft.NETFramework*csc.exe"') do set "csc=\%\%v"

"\%csc\%" -nologo -out:"\%exe\%.exe" "\%~f0"

endlocal
exit /b \%errorlevel\%

*/

using System;

namespace cw {
    class Program {
        static void Main() {
            var exe = Environment.GetCommandLineArgs()[0];
            var rawCmd = Environment.CommandLine;
            var line = rawCmd.Remove(rawCmd.IndexOf(exe),exe.Length).TrimStart('"');
            line = line.Length < 2 ? "
" : line.Substring(2) ;
            Console.Write(line);
        }
    }
}



  1. Kør det.

  2. Nu har du et godt 4KB-værktøj, så du kan slette .bat.



Alternativt kan du indsætte denne kode som en subrutine i en batch, send den resulterende .exe til \%temp\%, brug den i din batch og slet den, når du er færdig.


Sådan bruger du



Hvis du vil skrive noget uden ny linje:

cw Whatever you want, even with "", but remember to escape ^|, ^^, ^&, etc. unless double-quoted, like in "| ^ &".


Hvis du vil have en vognretur (går til starten af ​​linjen), kør bare

cw


Så prøv det fra kommandolinjen:


for /l \%a in (1,1,1000) do @(cw ^|&cw&cw /&cw&cw -&cw&cw &cw)

Andre referencer 10


Du kan undertrykke den nye linje ved at bruge kommandoen sæt/p. Set/p-kommandoen genkender ikke et mellemrum, for det kan du bruge en prik og et backspace-tegn til at gøre det genkende det. Du kan også bruge en variabel som en hukommelse og gemme, hvad du vil udskrive i det, så du kan udskrive variablen i stedet for sætningen. For eksempel:


@echo off
setlocal enabledelayedexpansion
for /f \%\%a in ('"prompt $H & for \%\%b in (1) do rem"') do (set "bs=\%\%a")
cls
set "var=Hello World! :)"
set "x=0"

:loop
set "display=!var:~\%x\%,1!"
<nul set /p "print=.\%bs\%\%display\%"
ping -n 1 localhost >nul
set /a "x=\%x\% + 1"
if "!var:~\%x\%,1!" == "" goto end
goto loop

:end
echo.
pause
exit


På denne måde kan du udskrive alt uden en ny linje. Jeg har lavet programmet til at udskrive tegnene en ad gangen, men du kan også bruge ord i stedet for tegn ved at ændre sløjfen.


I ovenstående eksempel brugte jeg 'enabledelayedeexpansion', så sæt/p-kommandoen genkender ikke '!' tegn og udskriver en prik i stedet for det. Jeg håber, at du ikke har brug for udråbstegn '!';)

Andre referencer 11


Prøve 1: Dette virker og producerer Afslutskode=0. Det er godt.
Bemærk '.' , direkte efter ekko.



  C: \ Users \ phife.dog \ gitrepos \ 1 \ repo\_abc \ scripts #

  @echo. | set/p JUNK\_VAR=Dette er en besked, der vises som Linux-ekko-jeg ville vise det ... & ekko\% ERRORLEVEL\%



Dette er en besked, der vises som Linux-ekko-jeg ville vise det ... 0


Prøve 2: Dette virker men producerer Afslutskode=1. Det er dårligt.
Bemærk venligst manglen på '.', Efter ekko. Det ser ud til at være forskellen.



  C: \ Users \ phife.dog \ gitrepos \ 1 \ repo\_abc \ scripts #

  @echo | set/p JUNK\_VAR=Dette er en besked, der vises som Linux-ekko-jeg ville vise det ... & ekko\% ERRORLEVEL\%



Dette er en besked, der vises som Linux-ekko. Jeg ville vise det ... 1

Andre referencer 12


Jeg tror der er ingen sådan mulighed. Alternativt kan du prøve dette


set text=Hello
set text=\%text\% world
echo \%text\%

Andre referencer 13


Sen svar her, men for alle, der har brug for at skrive specialtegn til en enkelt linje, der finder dbenhams svar til at være omkring 80 linjer for længe, ​​og hvis scripts kan bryde (måske på grund af brugerindlæsning) under begrænsningerne ved simpelthen at bruge [[set /p, er det nok nemmest at bare parre din .bat eller .cmd med en kompileret C + + eller C-sprog eksekverbar og så kun cout eller printf tegnene. Dette vil også give dig mulighed for nemt at skrive flere gange til en linje, hvis du viser en slags fremdriftslinje eller noget ved hjælp af tegn, som OP tilsyneladende var.

Andre referencer 14


Jeg lavede en funktion ud af @arneps idé:



  echo | set/p='Hej verden'



her er det:


:SL (sameline)
echo|set /p=\%1
exit /b


Brug det med call :SL "Hello There"

Jeg ved, at dette ikke er noget særligt, men det tog mig så lang tid at tænke på det, jeg regnede med, jeg kunne skrive det her.

Andre referencer 15


du kan bruge udskiftnings kommandoen printf eller udskrive og bruge vognretur i det for at opnå dette


ex: printf 'Hello World \ r'


Den fulde syntaks er tilgængelig her:
http://wiki.bash-hackers.org/commands/builtin/printf[53]