Odpowiedzi:
Ten skrypt zrobi dokładnie to, o co prosiłeś:
@echo off
setlocal enableextensions enabledelayedexpansion
for /f %%a in ('copy /Z "%~dpf0" nul') do set "ASCII_13=%%a"
set /p "=Step 1" <NUL
REM Do some stuff...
set /p "=!ASCII_13!Step 2" <NUL
REM do some other stuff...
Znalazłem tę odpowiedź, patrząc na kod w bibliotece do manipulacji znakami skryptów wsadowych napisanej przez Dave'a Benhama o nazwie CharLib .
Ta biblioteka jest w stanie utworzyć wszystkie znaki z zakresu 1..255.
Aby uzyskać więcej informacji, zobacz temat zatytułowany „Czy można przekonwertować znak na jego wartość ASCII?”
Edytuj 2017-4-26: Wygląda na to, że powyższy kod już nie działa . Nie jestem pewien, kiedy to zachowanie by się zmieniło, ale na pewno zadziałało. CR
Znak po =
teraz zostaje pozbawiony przez set
komendę. Ach, wydaje się, że jest to zmiana w sposobie set
działania między XP a nowszymi wersjami systemu Windows. Widzisz doskonałą odpowiedź w wierszu Zastąp w pliku wsadowym systemu Windows? (duplikat), aby uzyskać więcej szczegółów i dodatkowe przykłady kodu.
Alternatywą jest zatem umieszczenie przed spacją znaku spacji !ASCII_13!
i ustawienie go również do usunięcia, być może albo przez wstawienie spacji (która nie jest usuwana), a następnie spacji lub przez dodanie spacji na końcu ciąg zachęty (który nie jest usuwany).
Np. Tak:
@echo off
setlocal enableextensions enabledelayedexpansion
for /f %%a in ('copy /Z "%~dpf0" nul') do set "ASCII_13=%%a"
set /p "=Step 1" <NUL
REM Do some stuff...
set /p "=x!ASCII_13!Step 2 " <NUL
REM do some other stuff...
set
polecenie teraz usuwa Znaki CR i LF (oraz spacje) po =
. Spróbuj =
!ACSII_13!
set /p "=Step 2 " <NUL
Aby odpowiedzieć na pytanie:
@echo off
CALL :EVALUATE "chr(8)"
SET backspace=%result%
<nul set /p =Step 1
:: DO SOME STUFF....
<nul set /p =%backspace%
<nul set /p =2
:: DO SOME OTHER STUFF....
<nul set /p =%backspace%%backspace%%backspace%%backspace%%backspace%%backspace%
<nul set /p =End
GOTO:EOF
:EVALUATE -- evaluate with VBS and return to result variable
:: -- %~1: VBS string to evaluate
:: extra info: http://groups.google.com/group/alt.msdos.batch.nt/browse_thread/thread/9092aad97cd0f917
@IF [%1]==[] ECHO Input argument missing & GOTO :EOF
@ECHO wsh.echo "result="^&eval("%~1") > %temp%\evaluate_tmp_67354.vbs
@FOR /f "delims=" %%a IN ('cscript //nologo %temp%\evaluate_tmp_67354.vbs') do @SET "%%a"
@DEL %temp%\evaluate_tmp_67354.vbs
::ECHO %result%
@GOTO:EOF
Wynik:
End
Zasadniczo, co robi skrypt, to pisze Step 1
, a następnie cofa się o jedno miejsce nadpisuje 1
, a na końcu przechodzi całkowicie do tyłu i nadpisuje Step 2
z End
.
Wracając, robię to ze specjalnym znakiem ASCII 8, którym jest backspace. Ponieważ nie wiem, jak napisać to w cmd, używam funkcji: EVALUATE, która uruchamia funkcję VBS Chr () i wstawia znak backspace do zmiennej result
. Jeśli ktoś zna lepszy sposób, proszę o poradę.
$host.ui.RawUI.CursorPosition
zmienną i przywrócić ją później, aby kursor przeskoczył z powrotem do miejsca, w którym się znajdowałeś, i zastąpić dane wyjściowe. Tylko opcja dla PowerShell, ale może być nieco czystsza niż twoje VBS :-)
@echo off
for /F "tokens=1 delims=# " %%a in ('"prompt #$H# & echo on & for %%b in (1) do rem"') do set "BSPACE=%%a"
<nul set /p =Step 1
ping 127.0.0.1 >nul
<nul set /p =%BSPACE%
<nul set /p =2
ping 127.0.0.1 >nul
<nul set /p =%BSPACE%
<nul set /p =3
ping 127.0.0.1 >nul
<nul set /p =%BSPACE%%BSPACE%%BSPACE%%BSPACE%%BSPACE%%BSPACE%
<nul set /p =End.
pause
WYJAŚNIENIE:
for /F "tokens=1 delims=# " %%a in ('"prompt #$H# & echo on & for %%b in (1) do rem"') do set "BSPACE=%%a"
ustawi to znak backspace w zmiennej BSPACE. Teraz, aby zobaczyć wynik, wpisz:
echo ab%BSPACE%c
wynik:
ac
możesz użyć tej zmiennej BSPACE więcej niż jeden raz, aby usunąć wiele znaków.
Teraz, jeśli chcesz ustawić powrót karetki w zmiennej, użyj
for /F "usebackq" %%a in (
copy / Z "% ~ dpf0" nul) DO (set "cr=%%a")
aby zobaczyć wynik, wpisz:
setlocal EnableDelayedExpansion
& echo asfasdhlfashflkashflksa!CR!***
wyjście będzie:
***asfasdhlfashflkashflksa
Powyższa odpowiedź @ davour jest również piękna, ale odpowiedź @ timfoden nie zadziałała dla mnie.
set /p "=.!CR!End. " <NUL&echo:
Nie możesz Zazwyczaj można to osiągnąć, umieszczając w pliku znak powrotu karetki (0x0D), który umieści kursor z powrotem w pierwszej kolumnie w tym samym wierszu. Ale w tym przypadku to nie działa; CR jest po prostu zjadany w ciszy.
Ponadto uzyskanie CR jest tam trochę trudne i przynajmniej w tym przypadku zaangażowany jest edytor tekstu. Sugeruję napisanie małego programu narzędziowego, który zrobi to za Ciebie, w rzeczywistości nie jest to bardzo trudne. Następujący mały program C może wystarczyć (jeśli nie potrzebujesz Unicode):
#include <stdio.h>
int main(int argc, char* argv[]) {
if (argc < 2) return 1;
printf("\r%s", argv[1]);
}
Nie robi nic poza drukowaniem znaku CR, a następnie tekstu, który podajesz jako pierwszy argument. Zastosowanie w następujący sposób:
@echo off
<nul set /P X=Step 1
pause>nul 2>nul
over.exe "Step 2"
Ostatnia linia to wywołanie tego programu. Druga linia to zwykły idiom wsadowy do drukowania tekstu bez końcowego podziału linii (co jest ważne w tym przypadku, ponieważ w przeciwnym razie nie można nadpisać linii). Jednak równie dobrze możesz użyć powyższego programu w tym miejscu.
Lekko zhackowany sposób, ale jedynym, w którym możesz być pewien, gdzie skończysz, będzie użycie cls
przed wyjściem z kroku. Migocze, ale w ten sposób zawsze piszesz w lewym górnym rogu. I spychaj wszystko, co było widoczne w konsoli (dlatego nie polecałbym tego); większość użytkowników nie lubi tego zbytnio.
timeout 5
będzie działać.
for /f %%a in ('copy /Z "%~f0" nul') do set "CR=%%a"
Uzyskaj znak nowej linii, napisz następny krok, wróć na początek linii, napisz następny wiersz:
@echo off
cls
setlocal enabledelayedexpansion
echo Here's how it's done:
for /f %%a in ('copy /Z "%~f0" nul') do set "Newline=%%a"
set /p "=Step 1!Newline!" <NUL
REM Do some stuff...
ping -n 2 localhost > nul
set /p "=Step 2!Newline!" <NUL
ping -n 2 localhost > nul
set /p "=Step 3 " <NUL
REM do some other stuff...
ping -n 2 localhost > nul
echo:
echo Done.
Step 1
Step 2
Step 3
wszystkie są tej samej długości. Jeśli nie, tekst pierwszego set /p
pozostaje. Nie jestem pewien, jak to naprawić.
set /p "=Step 2SPACESPACESPACESPACE!Newline!" <NUL
w przeciwieństwie do set /p "=Step 2!Newline!" <NUL
. Wymień się SPACE
na postać.
Potrzebna byłaby biblioteka kursora ekranowego, taka jak curses
lub ncurses
, ale nie jestem zbyt obeznana z ich użyciem. Obie biblioteki zostały opracowane dla systemów uniksowych, ale można je znaleźć dla systemu Windows (w środowisku Cygwin lub GnuWin32 ).
Nie znam żadnego łatwego sposobu na dostęp do nich w pliku wsadowym w stylu DOS. Lepiej jest programować w skompilowanym języku. Spójrz na Ncurses HOWTO, aby dowiedzieć się, czy będzie przydatny.
W Notepad ++ można bezpośrednio wstawić Backspace ←znak (ASCII 0x08), korzystając z panelu wstawiania kodów ASCII (Edycja> Panel znaków).
Moim rozwiązaniem jest wstawienie [BS]
znaku bezpośrednio, a następnie, podobnie jak inne opublikowane tutaj rozwiązania, użyj go wiele razy, aby usunąć poprzednie znaki:
Kod
@ECHO OFF
SET "BACKSPACE_x7=[BS][BS][BS][BS][BS][BS][BS]"
SET /P "DUMMY_VAR=Step 1" < NUL
REM Do some stuff...
SET /P "DUMMY_VAR=%BACKSPACE_x7%Step 2" < NUL
REM Do some other stuff...
GOTO :EOF
Zrzut ekranu Notepad ++
Wynik
Inną możliwością jest użycie cechyo (polecenie echa z obsługą kolorów), aby wstawić Carriage Return ↵znak Unicode (U + 000D):
Kod
@ECHO OFF
SET CARRIAGE_RETURN={\u000D}
cecho Step 1
REM Do some stuff...
cecho %CARRIAGE_RETURN%Step 2
REM Do some other stuff...
GOTO :EOF
Uwaga: cecho_x64.exe
działa na mojej maszynie znacznie szybciej niż cecho.exe
.