Что такое пакетный эквивалент Windows команды оболочки Linux echo -n
, который подавляет новую строку в конце вывода?
Идея состоит в том, чтобы писать на одной строке внутри цикла.
Что такое пакетный эквивалент Windows команды оболочки Linux echo -n
, который подавляет новую строку в конце вывода?
Идея состоит в том, чтобы писать на одной строке внутри цикла.
Используя set
и параметр /p
, вы можете эхо без новой строки:
C:\> echo Hello World
Hello World
C:\> echo|set /p="Hello World"
Hello World
C:\>
Использование: echo | set /p=
или <NUL set /p=
будет работать для подавления новой строки.
Однако это может быть очень опасно при написании более сложных скриптов при проверке ERRORLEVEL становится важным, поскольку установка set /p=
без указания имени переменной устанавливает ERRORLEVEL равным 1.
Лучшим подходом было бы просто использовать имя фиктивной переменной, например: 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
оптимизированы таким образом, что только строки, содержащие неприятные ведущие символы, записываются с использованием моей модифицированной версии метода jeb 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
Это добавит дополнительное пространство в конце напечатанной строки, что может быть неудобно, особенно потому, что мы пытаемся избежать добавления новой строки (другого символа пробела) до конца строки.
К счастью, цитируя строку для печати, то есть используя:
echo | set /p dummyName="Hello World" > somefile.txt
Выведет строку без символа новой строки или пробела в конце.
Решение для выделенного пробела в SET/P:
трюк заключается в том, что backspace char, который вы можете вызвать в текстовом редакторе EDIT для DOS. Чтобы создать его в EDIT, нажмите ctrlP + ctrlH. Я бы вставлял его здесь, но эта веб-страница не может отображать его. Он был заметен на "Блокноте" (хотя он был похож на маленький черный прямоугольник с белым кругом в центре)
Итак, вы пишете это:
<nul set /p=.9 Hello everyone
Точкой может быть любой char, только там, чтобы сообщить SET/P, что текст начинается там, перед пробелами, а не в "Привет". " 9" - это представление обратного пространства char, которое я не могу отобразить здесь. Вы должны положить его вместо 9, и он удалит ".", после чего вы получите следующее:
Hello Everyone
вместо:
Hello Everyone
Я надеюсь, что это поможет
Вы можете удалить новую строку, используя "tr" из пакета gnuwin32 (coreutils)
@echo off
set L=First line
echo %L% | tr -d "\r\n"
echo Second line
pause
Кстати, если вы делаете много скриптов, gnuwin32 - золотая жила.
Вот еще один способ: он использует PowerShell Write-Host, который имеет параметр -NoNewLine, объединяет его с start /b
и предлагает те же функциональные возможности из пакета.
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
Выход
Result 1 - Result 2 - Result 3 - Press any key to continue . . .
Этот ниже немного отличается, не работает точно так, как хочет OP, но интересен тем, что каждый результат перезаписывает предыдущий результат, эмулирующий счетчик.
@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
<nul set /p =Testing testing
а также эхо, начиная с использования пробелов
echo.Message goes here
Возможно, это то, что вы ищете, это старая школа 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
или, может быть, вы пытаетесь заменить текущую строку вместо записи на новую строку? вы можете поэкспериментировать с этим, удалив "% bs%" после ".". а также путем выделения другого "% bs%" после "Пример сообщения".
for /f %%a in ('"prompt $H&for %%b in (1) do rem"') do set "bs=%%a"
<nul set /p=.%bs% Example message %bs%
pause
Я нахожу это действительно интересным, потому что он использует переменную для цели, отличной от того, что она предназначена. как вы видите, "% bs%" представляет собой обратное пространство. Второй "% bs%" использует обратное пространство для добавления пробелов после сообщения "Пример" для разделения "вывода команды" Пауза "без фактического добавления видимого символа после" Пример сообщения ". Однако это также возможно с помощью обычного знака процента.
cw.exe
DIY cw.exe
(консольная запись) Если вы не найдете его готовым, готовым, вы можете сделать DIY. С помощью этой утилиты cw
вы можете использовать все типы символов. По крайней мере, я бы так хотел. Пожалуйста, стресс-тест и дайте мне знать.
Все, что вам нужно, это .NET, который очень распространен в наши дни.
Некоторые символы напечатаны/скопированы.
.bat
со следующим содержимым./* >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);
}
}
}
Запустить его.
Теперь у вас есть хорошая утилита 4KB, поэтому вы можете удалить .bat
.
В качестве альтернативы вы можете вставить этот код в качестве подпрограммы в любой партии, отправить полученный .exe
в %temp%
, использовать его в своей партии и удалить его, когда закончите.
Если вы хотите написать что-то без новой строки: cw Whatever you want, even with "", but remember to escape ^|, ^^, ^&, etc. unless double-quoted, like in "| ^ &".
Если вы хотите вернуть карету (переход к началу строки), запустите cw
Поэтому попробуйте это из командной строки:
for /l %a in (1,1,1000) do @(cw ^|&cw&cw /&cw&cw -&cw&cw \&cw)
Я сделал функцию из идеи @arnep:
echo | set/p = "Hello World"
вот:
:SL (sameline)
echo|set /p=%1
exit /b
Используйте его с call :SL "Hello There"
Я знаю, что это ничего особенного, но мне потребовалось столько времени, чтобы подумать об этом, я подумал, что отправлю его здесь.
Пример 1: Это работает и создает код выхода = 0. Это хорошо. Обратите внимание "." , непосредственно после эха.
C:\Users\phife.dog\gitrepos\1\repo_abc\scripts #
@echo. | set/p JUNK_VAR = Это сообщение, отображаемое как echo Linux -n, отобразит его... & echo% ERRORLEVEL%
Это сообщение отображается как Linux echo -n будет отображать его... 0
Пример 2: Это работает, но дает код выхода = 1. Это плохо. Обратите внимание на отсутствие ".", После эха. Кажется, это разница.
C:\Users\phife.dog\gitrepos\1\repo_abc\scripts #
@echo | set/p JUNK_VAR = Это сообщение, отображаемое как echo Linux -n, отобразит его... & echo% ERRORLEVEL%
Это сообщение отображается как Linux echo -n будет отображать его... 1
Я считаю, что такого выбора нет. В качестве альтернативы вы можете попробовать это
set text=Hello
set text=%text% world
echo %text%
Поздний ответ здесь, но для тех, кто должен писать специальные символы в одну строку, которые находят dbenham ответ, чтобы быть около 80 строк слишком длинными и чьи скрипты могут сломаться (возможно, из-за пользовательского ввода) в рамках ограничений простого использования set /p
, проще всего просто соединить ваш .bat или .cmd с скомпилированным исполняемым С++ или C-языком, а затем просто cout
или printf
персонажи. Это также позволит вам легко писать несколько раз в одну строку, если вы показываете своего рода индикатор выполнения или что-то с помощью символов, поскольку OP, по-видимому, был.
Вы можете подавить новую строку, используя команду set/p. Команда set/p не распознает пробел, для чего вы можете использовать символ точки и обратного пространства, чтобы распознать его. Вы также можете использовать переменную в качестве памяти и хранить в ней то, что вы хотите напечатать, чтобы вы могли печатать переменную вместо предложения. Например:
@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
Таким образом вы можете печатать все без новой строки. Я заставил программу печатать символы один за другим, но вы можете использовать слова вместо символов, изменяя цикл.
В приведенном выше примере я использовал "enabledelayedexpansion", поэтому команда set/p не распознает "!" и вместо этого печатает точку. Я надеюсь, что вы не используете восклицательный знак "!".;)
вы можете использовать замену команды printf или распечатать и использовать возврат каретки в ней для достижения этого
ex: printf "Hello World\r"
Полный синтаксис доступен здесь: http://wiki.bash-hackers.org/commands/builtin/printf