Windows 배치 : 줄 바꿈없이 에코
echo -n
출력이 끝날 때 줄 바꿈을 억제하는 Linux 셸 명령과 동등한 Windows 배치는 무엇입니까 ?
아이디어는 루프 내에서 같은 줄에 쓰는 것입니다.
개행없이 에코 set
와 /p
매개 변수를 사용하여 :
C:\> echo Hello World
Hello World
C:\> echo|set /p="Hello World"
Hello World
C:\>
사용 : echo | set /p=
또는 <NUL set /p=
둘 다 줄 바꿈을 억제합니다.
그러나 set /p=
변수 이름을 지정하지 않고 설정하면 ERRORLEVEL이 1로 설정되므로 ERRORLEVEL을 확인할 때 고급 스크립트를 작성할 때 매우 위험 할 수 있습니다 .
더 좋은 방법은 더미 변수 이름을 다음과 같이 사용하는 것입니다.
echo | set /p dummyName=Hello World
이것은 어려운 방법을 찾아야했기 때문에 배경에서 교활한 물건을 사용하지 않고 원하는 것을 정확하게 생성하지만 파이프 버전에서만 작동합니다. <NUL set /p dummyName=Hello
여전히 ERRORLEVEL을 1로 올립니다.
간단한 SET / P 방법에는 Windows 버전마다 약간의 제한이 있습니다.
선행 인용 부호가 제거 될 수 있습니다
선행 공백이 제거 될 수 있습니다.
선행
=
구문 오류가 발생합니다.
자세한 내용은 http://www.dostips.com/forum/viewtopic.php?f=3&t=4209 를 참조하십시오.
jeb는 선행 공백이 있더라도 줄 바꿈없이 출력 텍스트 의 대부분의 문제를 해결하는 영리한 솔루션을 게시했습니다. 또는 모든 버전의 Windows에서 줄 바꿈없이 유효한 배치 문자열을 안전하게 인쇄 할 수 있도록 방법을 개선했습니다. XP부터. 이 :writeInitialize
메서드에는 사이트에 제대로 게시되지 않을 수있는 문자열 리터럴이 포함되어 있습니다. 문자 순서가 무엇인지 설명하는 설명이 포함되어 있습니다.
:write
및 :writeVar
방법은 번잡 한 최고의 문자가 포함 된 문자열 만이 젭의 COPY 방법의 내 수정 된 버전을 사용하여 작성되도록 최적화되어 있습니다. 까다 롭지 않은 문자열은 더 간단하고 빠른 SET / P 방법을 사용하여 작성됩니다.
@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
@xmechanix의 답변에 대한 부록으로 파일에 내용을 쓰는 것으로 나타났습니다.
echo | set /p dummyName=Hello World > somefile.txt
That this will add an extra space at the end of the printed string, which can be inconvenient, specially since we're trying to avoid adding a new line (another whitespace character) to the end of the string.
Fortunately, quoting the string to be printed, i.e. using:
echo | set /p dummyName="Hello World" > somefile.txt
Will print the string without any newline or space character at the end.
A solution for the stripped white space in SET /P:
the trick is that backspace char which you can summon in the text editor EDIT for DOS. To create it in EDIT press ctrlP+ctrlH. I would paste it here but this webpage can't display it. It's visible on Notepad though (it's werid, like a small black rectangle with a white circle in the center)
So you write this:
<nul set /p=.9 Hello everyone
The dot can be any char, it's only there to tell SET /P that the text starts there, before the spaces, and not at the "Hello". The "9" is a representation of the backspace char that I can't display here. You have to put it instead of the 9, and it will delete the "." , after which you'll get this:
Hello Everyone
instead of:
Hello Everyone
I hope it helps
You can remove the newline using "tr" from gnuwin32 (coreutils package)
@echo off
set L=First line
echo %L% | tr -d "\r\n"
echo Second line
pause
By the way, if you are doing lots of scripting, gnuwin32 is a goldmine.
Here is another method, it uses Powershell Write-Host which has a -NoNewLine parameter, combine that with start /b
and it offers the same functionality from 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
Output
Result 1 - Result 2 - Result 3 - Press any key to continue . . .
This one below is slightly different, doesn't work exactly like the OP wants, but is interesting because each result overwrites the previous result emulating a counter.
@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
From here
<nul set /p =Testing testing
and also to echo beginning with spaces use
echo.Message goes here
Maybe this is what your looking for, it's a old school 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
or maybe your trying to replace a current line instead of writing to a new line? you can experiment with this by removing the "%bs%" after the "." sign and also by spacing out the other "%bs%" after the "Example message".
for /f %%a in ('"prompt $H&for %%b in (1) do rem"') do set "bs=%%a"
<nul set /p=.%bs% Example message %bs%
pause
I find this really interesting because it uses a variable for a purpose other than what it is intended to do. as you can see the "%bs%" represents a backspace. The second "%bs%" uses the backspace to add spaces after the "Example message" to separate the "Pause command's output" without actually adding a visible character after the "Example message". However, this is also possible with a regular percentage sign.
DIY cw.exe
(console write) utility
If you don't find it out-of-the-box, off-the-shelf, you can DIY. With this cw
utility you can use every kind of characters. At least, I'd like to think so. Please stress-test it and let me know.
Tools
All you need is .NET installed, which is very common nowadays.
Materials
Some characters typed/copy-pasted.
Steps
- Create
.bat
file with the following content.
/* >nul 2>&1
@echo off
setlocal
set exe=cw
for /f "tokens=* delims=" %%v in ('dir /b /s /a:-d /o:-n "%SystemRoot%\Microsoft.NET\Framework\*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 ? "\r" : line.Substring(2) ;
Console.Write(line);
}
}
}
Run it.
Now you have a nice 4KB utility so you can delete the
.bat
.
Alternatively, you can insert this code as a subroutine in any batch, send the resulting .exe
to %temp%
, use it in your batch and delete it when you're done.
How to use
If you want write something without new line:
cw Whatever you want, even with "", but remember to escape ^|, ^^, ^&, etc. unless double-quoted, like in "| ^ &".
If you want a carriage return (going to the beginning of the line), run just
cw
So try this from command line:
for /l %a in (1,1,1000) do @(cw ^|&cw&cw /&cw&cw -&cw&cw \&cw)
I made a function out of @arnep 's idea:
echo|set /p="Hello World"
here it is:
:SL (sameline)
echo|set /p=%1
exit /b
Use it with call :SL "Hello There"
I know this is nothing special but it took me so long to think of it I figured I'd post it here.
Sample 1: This works and produces Exit code = 0. That is Good. Note the "." , directly after echo.
C:\Users\phife.dog\gitrepos\1\repo_abc\scripts #
@echo.| set /p JUNK_VAR=This is a message displayed like Linux echo -n would display it ... & echo %ERRORLEVEL%
This is a message displayed like Linux echo -n would display it ... 0
Sample 2: This works but produces Exit code = 1. That is Bad. Please note the lack of ".", after echo. That appears to be the difference.
C:\Users\phife.dog\gitrepos\1\repo_abc\scripts #
@echo | set /p JUNK_VAR=This is a message displayed like Linux echo -n would display it ... & echo %ERRORLEVEL%
This is a message displayed like Linux echo -n would display it ... 1
I believe there's no such option. Alternatively you can try this
set text=Hello
set text=%text% world
echo %text%
Late answer here, but for anyone who needs to write special characters to a single line who find dbenham's answer to be about 80 lines too long and whose scripts may break (perhaps due to user-input) under the limitations of simply using set /p
, it's probably easiest to just to pair your .bat or .cmd with a compiled C++ or C-language executable and then just cout
or printf
the characters. This will also allow you to easily write multiple times to one line if you're showing a sort of progress bar or something using characters, as OP apparently was.
You can suppress the new line by using the set /p command. The set /p command does not recognize a space, for that you can use a dot and a backspace character to make it recognize it. You can also use a variable as a memory and store what you want to print in it, so that you can print the variable instead of the sentence. For example:
@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
In this way you can print anything without a new line. I have made the program to print the characters one by one, but you can use words too instead of characters by changing the loop.
In the above example I used "enabledelayedexpansion" so the set /p command does not recognize "!" character and prints a dot instead of that. I hope that you don't have the use of the exclamation mark "!" ;)
참고URL : https://stackoverflow.com/questions/7105433/windows-batch-echo-without-new-line
'IT story' 카테고리의 다른 글
Go에서 빈 문자열을 테스트하는 가장 좋은 방법은 무엇입니까? (0) | 2020.05.01 |
---|---|
스팬 요소의 줄 바꿈 방지 (0) | 2020.05.01 |
XML 스키마 minOccurs / maxOccurs 기본값 (0) | 2020.05.01 |
여러 모듈에서 Python 로깅 사용 (0) | 2020.05.01 |
왜 emplace_back 대신 push_back을 사용합니까? (0) | 2020.05.01 |