Jak echo z różnymi kolorami w wierszu poleceń systemu Windows


217

Wiem, że color bfpolecenie ustawia kolory całego okna wiersza poleceń, ale chciałem wydrukować jedną linię w innym kolorze.


1
Wydaje się, że nie ma żadnego prostego sposobu na dodanie kodów kolorów do wiersza poleceń systemu Windows. :(
rui

rui, jeśli Win10 jest akceptowalną wersją systemu operacyjnego, sprawdź odpowiedź Jensa - powinna być dokładnie tym, czego potrzebujesz, ponieważ to pytanie nigdy nie zaakceptowało odpowiedzi siedem lat temu: stackoverflow.com/a/38617204/3543437
kayleeFrye_onDeck

Odpowiedzi:


284

Chciałem wydrukować jedną linię w innym kolorze.

Użyj sekwencji ucieczki ANSI.

Windows przed 10 - brak natywnej obsługi kolorów ANSI na konsoli

W przypadku wersji Windows poniżej 10 konsola poleceń Windows domyślnie nie obsługuje kolorowania wydruków. Możesz zainstalować Cmder , ConEmu , ANSICON lub Mintty (domyślnie używane w GitBash i Cygwin), aby dodać obsługę kolorowania do konsoli poleceń Windows.

Windows 10 - Kolory linii poleceń

Począwszy od systemu Windows 10 konsola Windows domyślnie obsługuje sekwencje specjalne ANSI i niektóre kolory. Funkcja dostarczona z aktualizacją Threshold 2 w listopadzie 2015 r.

Dokumentacja MSDN

Aktualizacja (05-2019): ColorTool umożliwia zmianę schematu kolorów konsoli. Jest to część projektu Microsoft Terminal .

Próbny

wprowadź opis zdjęcia tutaj

Polecenie wsadowe

win10colors.cmdZostał napisany przez Michele locati :

@echo off
cls
echo [101;93m STYLES [0m
echo ^<ESC^>[0m [0mReset[0m
echo ^<ESC^>[1m [1mBold[0m
echo ^<ESC^>[4m [4mUnderline[0m
echo ^<ESC^>[7m [7mInverse[0m
echo.
echo [101;93m NORMAL FOREGROUND COLORS [0m
echo ^<ESC^>[30m [30mBlack[0m (black)
echo ^<ESC^>[31m [31mRed[0m
echo ^<ESC^>[32m [32mGreen[0m
echo ^<ESC^>[33m [33mYellow[0m
echo ^<ESC^>[34m [34mBlue[0m
echo ^<ESC^>[35m [35mMagenta[0m
echo ^<ESC^>[36m [36mCyan[0m
echo ^<ESC^>[37m [37mWhite[0m
echo.
echo [101;93m NORMAL BACKGROUND COLORS [0m
echo ^<ESC^>[40m [40mBlack[0m
echo ^<ESC^>[41m [41mRed[0m
echo ^<ESC^>[42m [42mGreen[0m
echo ^<ESC^>[43m [43mYellow[0m
echo ^<ESC^>[44m [44mBlue[0m
echo ^<ESC^>[45m [45mMagenta[0m
echo ^<ESC^>[46m [46mCyan[0m
echo ^<ESC^>[47m [47mWhite[0m (white)
echo.
echo [101;93m STRONG FOREGROUND COLORS [0m
echo ^<ESC^>[90m [90mWhite[0m
echo ^<ESC^>[91m [91mRed[0m
echo ^<ESC^>[92m [92mGreen[0m
echo ^<ESC^>[93m [93mYellow[0m
echo ^<ESC^>[94m [94mBlue[0m
echo ^<ESC^>[95m [95mMagenta[0m
echo ^<ESC^>[96m [96mCyan[0m
echo ^<ESC^>[97m [97mWhite[0m
echo.
echo [101;93m STRONG BACKGROUND COLORS [0m
echo ^<ESC^>[100m [100mBlack[0m
echo ^<ESC^>[101m [101mRed[0m
echo ^<ESC^>[102m [102mGreen[0m
echo ^<ESC^>[103m [103mYellow[0m
echo ^<ESC^>[104m [104mBlue[0m
echo ^<ESC^>[105m [105mMagenta[0m
echo ^<ESC^>[106m [106mCyan[0m
echo ^<ESC^>[107m [107mWhite[0m
echo.
echo [101;93m COMBINATIONS [0m
echo ^<ESC^>[31m                     [31mred foreground color[0m
echo ^<ESC^>[7m                      [7minverse foreground ^<-^> background[0m
echo ^<ESC^>[7;31m                   [7;31minverse red foreground color[0m
echo ^<ESC^>[7m and nested ^<ESC^>[31m [7mbefore [31mnested[0m
echo ^<ESC^>[31m and nested ^<ESC^>[7m [31mbefore [7mnested[0m

11
@Jens A. Koch - nie działa w mojej konsoli Windows 10 (cmd)
user3057544

40
Dobrze. Dziękujemy za opinię. .cmdlub .bat- oba powinny działać. Ale myślę, że wiem, dlaczego to nie działa: wydaje się, że symbol ucieczki został usunięty podczas wysyłania do StackOverflow. Proszę nie kopiować treści z mojej odpowiedzi, zamiast tego użyj treści z tego miejsca: gist.githubusercontent.com/mlocati/…
Jens A. Koch

28
Nigdy wcześniej nie musiałem generować ESCw notatniku ++ ... Możesz to zrobić za pomocą kodów ALT za pomocą klawiatury numerycznej i lewego klawisza ALT: L-ALT+ 0+ 2+7
kayleeFrye_onDeck

3
Btw, jako ktoś, kto produkuje i używa dużo partii przez większość dni, ta odpowiedź poprawiła mój ogólny zestaw narzędzi w estetyczny sposób! Używasz VB? Piekło nie To jest najlepsza droga!
kayleeFrye_onDeck

4
Możesz wygenerować ESCznak w pliku wsadowym w następujący sposób:for /F %%a in ('echo prompt $E ^| cmd') do set "ESC=%%a"
Aacini

56

Jest to samodzielnie skompilowana hybryda bat / .net (powinna zostać zapisana jako .BAT), której można używać w dowolnym systemie, w którym zainstalowano platformę .net (rzadko można zobaczyć okna bez architektury .NET nawet w przypadku najstarszych XP / 2003 instalacje). Używa kompilatora jscript.net, aby utworzyć plik exe zdolny do drukowania ciągów o innym kolorze tła / pierwszego planu tylko dla bieżącej linii.

@if (@X)==(@Y) @end /* JScript comment
@echo off
setlocal

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

if not exist "%~n0.exe" (
    "%jsc%" /nologo /out:"%~n0.exe" "%~dpsfnx0"
)

%~n0.exe %*

endlocal & exit /b %errorlevel%

*/

import System;

var arguments:String[] = Environment.GetCommandLineArgs();

var newLine = false;
var output = "";
var foregroundColor = Console.ForegroundColor;
var backgroundColor = Console.BackgroundColor;
var evaluate = false;
var currentBackground=Console.BackgroundColor;
var currentForeground=Console.ForegroundColor;


//http://stackoverflow.com/a/24294348/388389
var jsEscapes = {
  'n': '\n',
  'r': '\r',
  't': '\t',
  'f': '\f',
  'v': '\v',
  'b': '\b'
};

function decodeJsEscape(_, hex0, hex1, octal, other) {
  var hex = hex0 || hex1;
  if (hex) { return String.fromCharCode(parseInt(hex, 16)); }
  if (octal) { return String.fromCharCode(parseInt(octal, 8)); }
  return jsEscapes[other] || other;
}

function decodeJsString(s) {
  return s.replace(
      // Matches an escape sequence with UTF-16 in group 1, single byte hex in group 2,
      // octal in group 3, and arbitrary other single-character escapes in group 4.
      /\\(?:u([0-9A-Fa-f]{4})|x([0-9A-Fa-f]{2})|([0-3][0-7]{0,2}|[4-7][0-7]?)|(.))/g,
      decodeJsEscape);
}


function printHelp( ) {
   print( arguments[0] + "  -s string [-f foreground] [-b background] [-n] [-e]" );
   print( " " );
   print( " string          String to be printed" );
   print( " foreground      Foreground color - a " );
   print( "                 number between 0 and 15." );
   print( " background      Background color - a " );
   print( "                 number between 0 and 15." );
   print( " -n              Indicates if a new line should" );
   print( "                 be written at the end of the ");
   print( "                 string(by default - no)." );
   print( " -e              Evaluates special character " );
   print( "                 sequences like \\n\\b\\r and etc ");
   print( "" );
   print( "Colors :" );
   for ( var c = 0 ; c < 16 ; c++ ) {
        
        Console.BackgroundColor = c;
        Console.Write( " " );
        Console.BackgroundColor=currentBackground;
        Console.Write( "-"+c );
        Console.WriteLine( "" );
   }
   Console.BackgroundColor=currentBackground;
   
   

}

function errorChecker( e:Error ) {
        if ( e.message == "Input string was not in a correct format." ) {
            print( "the color parameters should be numbers between 0 and 15" );
            Environment.Exit( 1 );
        } else if (e.message == "Index was outside the bounds of the array.") {
            print( "invalid arguments" );
            Environment.Exit( 2 );
        } else {
            print ( "Error Message: " + e.message );
            print ( "Error Code: " + ( e.number & 0xFFFF ) );
            print ( "Error Name: " + e.name );
            Environment.Exit( 666 );
        }
}

function numberChecker( i:Int32 ){
    if( i > 15 || i < 0 ) {
        print("the color parameters should be numbers between 0 and 15");
        Environment.Exit(1);
    }
}


if ( arguments.length == 1 || arguments[1].toLowerCase() == "-help" || arguments[1].toLowerCase() == "-help"   ) {
    printHelp();
    Environment.Exit(0);
}

for (var arg = 1; arg <= arguments.length-1; arg++ ) {
    if ( arguments[arg].toLowerCase() == "-n" ) {
        newLine=true;
    }
    
    if ( arguments[arg].toLowerCase() == "-e" ) {
        evaluate=true;
    }
    
    if ( arguments[arg].toLowerCase() == "-s" ) {
        output=arguments[arg+1];
    }
    
    
    if ( arguments[arg].toLowerCase() == "-b" ) {
        
        try {
            backgroundColor=Int32.Parse( arguments[arg+1] );
        } catch(e) {
            errorChecker(e);
        }
    }
    
    if ( arguments[arg].toLowerCase() == "-f" ) {
        try {
            foregroundColor=Int32.Parse(arguments[arg+1]);
        } catch(e) {
            errorChecker(e);
        }
    }
}

Console.BackgroundColor = backgroundColor ;
Console.ForegroundColor = foregroundColor ;

if ( evaluate ) {
    output=decodeJsString(output);
}

if ( newLine ) {
    Console.WriteLine(output);  
} else {
    Console.Write(output);
    
}

Console.BackgroundColor = currentBackground;
Console.ForegroundColor = currentForeground;

Oto komunikat pomocy:

wprowadź opis zdjęcia tutaj

Przykład :

coloroutput.bat -s "aa\nbb\n\u0025cc" -b 10 -f 3 -n -e

Możesz także znaleźć ten skrypt tutaj .

Możesz także sprawdzić funkcję koloru Carlosa -> http://www.dostips.com/forum/viewtopic.php?f=3&t=4453


13
Jakie to jest świetne. Plik nietoperza, który kompiluje znajdujący się w nim skrypt jscript i tylko w razie potrzeby - jestem pod wrażeniem. Nawet nie wiedziałem, że tam właśnie czeka kompilator jscript, który czeka na użycie. Dostajesz moją „niesamowitą nagrodę” za miesiąc. Należy wspomnieć, że pierwsze użycie będzie wolne (z powodu kompilacji).
Graham

4
Nie potrzebuję wystarczająco dużo kolorów, aby przejść do tego ekstremum, ale technika jest naprawdę imponująca i widzę, że używam jej gdzie indziej.
EM0,

47

To nie jest świetna odpowiedź, ale jeśli wiesz, że docelowa stacja robocza ma Powershell, możesz zrobić coś takiego (przy założeniu skryptu BAT / CMD):

CALL:ECHORED "Print me in red!"

:ECHORED
%Windir%\System32\WindowsPowerShell\v1.0\Powershell.exe write-host -foregroundcolor Red %1
goto:eof

Edycja: (teraz prostsze!)

To stara odpowiedź, ale pomyślałem, że trochę wyjaśnię i uproszczę

img

PowerShell jest teraz zawarty we wszystkich wersjach systemu Windows od 7. Dlatego składnię tej odpowiedzi można skrócić do prostszej postaci:

  • ścieżka nie musi być określona, ponieważ powinien on być w zmiennej środowiskowej już.
  • jednoznaczne polecenia można skracać . Na przykład możesz:
    • użyj -forezamiast-foregroundcolor
    • użyj -backzamiast-backgroundcolor
  • komendy można również użyć w zasadzie „ inline ” zamiast echo
    (zamiast tworzyć osobny plik wsadowy jak wyżej).

Przykład:

powershell write-host -fore Cyan This is Cyan text
powershell write-host -back Red This is Red background

Więcej informacji:

Pełna lista kolorów i więcej informacji jest dostępna w
- dokumentacji PowerShell dlaWrite-Host



14
Greate, działa dla mnie, ale jest zbyt wolne.
piątek

4
zdaję sobie sprawę, że jest to odpowiedź na rozwiązanie, ale PowerShell? ugh.
SgtPooki

2
Dlatego zacząłem od „To nie jest świetna odpowiedź”. Bardzo lubię Powershell, ale to przesada. ANSICON jest lepszy, jeśli poradzisz sobie z wdrożeniem go na komputerach docelowych.
Iain

Dziękuję za tę odpowiedź. Szukałem wysokiego i niskiego poziomu, aby uzyskać echo kolorowych wyników z pliku wsadowego w programie Powershell i to był jedyny. Nie jestem pewien, dlaczego tak długo trwa drukowanie (przy każdej rozmowie trwa około 1 sekundy), ale przynajmniej mogę to zrobić. Dziękuję Ci!
pizzafilms

29

Windows 10 - TH2 i nowszy:

(alias Wersja 1511, kompilacja 10586, wydanie 2015-11-10)

W wierszu polecenia:

echo ^[[32m HI ^[[0m

Używanie rzeczywistych klawiszy: echo Ctrl+ [[32m HI Ctrl+[[0mEnter

Powinieneś zobaczyć zielone „HI” poniżej.

Numery kodów można znaleźć tutaj:

Notatnik:

Aby zapisać to w notatniku, możesz wpisać w niego ESC, używając: Alt+ 027za pomocą klawiatury numerycznej, a następnie [32mczęści. Kolejna sztuczka, gdy byłem na laptopie, przekieruj powyższą linię do pliku, aby rozpocząć, a następnie wytnij i wklej:

echo echo ^[[32m HI ^[[0m >> batch_file.cmd

3
Alt + 027 było dokładnie tym, czego potrzebowałem!
Aleksander Stelmaczonek,

1
Alt + 027 nie działa w Eclipse / Java. Próbowałem też, \033ale nie ... jak mogę to zrobić w Javie?
derHugo,

w systemie Windows 10 i nowszym działa to w edytorze DOS i Notepad ++. Dzięki!
Junior Mayhé

17

Możesz po prostu tworzyć pliki o nazwie słowa do wydrukowania, używa findstr, który może drukować w kolorze, a następnie usuwa plik. Spróbuj tego przykładu:

@echo off
SETLOCAL EnableDelayedExpansion
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
  set "DEL=%%a"
)

call :ColorText 0a "green"
call :ColorText 0C "red"
call :ColorText 0b "cyan"
echo(
call :ColorText 19 "blue"
call :ColorText 2F "white"
call :ColorText 4e "yellow"

goto :eof

:ColorText
echo off
<nul set /p ".=%DEL%" > "%~2"
findstr /v /a:%1 /R "^$" "%~2" nul
del "%~2" > nul 2>&1
goto :eof

Uruchom, color /?aby uzyskać listę kolorów.


3
Ustawia kolory w wierszu poleceń systemu Windows. Czy możesz wyjaśnić, co to robi?
FeatureCreep

2
Ok, po prostu tworzy pliki z nazwą słowa do wydrukowania, używa findstr, który może drukować w kolorze, a następnie usuwa plik.
FeatureCreep

2
To imponujące! Pamiętaj, że kody kolorów są nieprawidłowe. Uruchom „kolor /?” aby zobaczyć rzeczywiste kody kolorów.
yoyo

3
Zauważ, że findstr może tylko koloryzować nazwę pliku , co oznacza, że ​​nie możesz użyć tej sztuczki do łańcuchów zawierających niedozwolone znaki ścieżki.
yoyo

3
Warto również zauważyć, że spowoduje to zastąpienie plików w tym samym katalogu, jeśli będą one miały nazwę tego, co próbujesz wydrukować ... to wcale nie jest dobre.
BrainSlugs83,

14

Możesz użyć ANSICON, aby włączyć kody terminali ANSI w starszych wersjach systemu Windows. Istnieją wersje 32- i 64-bitowe, których użyłem w Windows XP i Windows 7.


Nie można go uruchomić w systemie Windows 8.1. Awaria za każdym razem, gdy próbuję zainstalować.
EHerman

@EHerman Może to pytanie pomoże.
Bryan Ash

ANSICON nie jest potrzebny w późniejszych wersjach Win 10. Nie próbuj go tam używać.
Gringo Suave

6

Zirytował mnie również brak odpowiedniego kolorowania w cmd, więc zacząłem tworzyć cmdcolor . To tylko standardowe proxy, które szuka ograniczonego zestawu sekwencji kontrolnych ANSI / VT100 (innymi słowy, jak w bash), tj echo \033[31m RED \033[0m DEFAULT | cmdcolor.exe.

Użycie i pobieranie .


To jest fajne i umieściłem je w systemie menu gigantycznego skryptu kompilacji w mojej pracy. Mam tylko wołowinę, że plik binarny, który podajesz na tej stronie, jest 64-bitowy, więc nie będzie działał na naszej 32-bitowej maszynie. Ale nie było problemu, po prostu złapałem się za źródło i skompilowałem.
paddy

Ale jest 32-bitowy :) Oto wynik pliku GNU:cmdcolor.exe; PE32 executable for MS Windows (console) Intel 80386 32-bit
Alec Mev

To dziwne ... XP Pro odmówił uruchomienia, ale działało dobrze na moim Win7 64. Skompilowałem z Visual C ++, celując w Win32, i było w porządku.
paddy

Huh ... prawdopodobnie z powodu upx. Czy możesz skontaktować się ze mną przez e-mail?
Alec Mev,

6

Patrzyłem na to, ponieważ chciałem wprowadzić kilka prostych kolorów tekstu do pliku wsadowego Win7. Właśnie to wymyśliłem. Dzięki za pomoc.

@echo off
cls && color 08

rem .... the following line creates a [DEL] [ASCII 8] [Backspace] character to use later
rem .... All this to remove [:]
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (set "DEL=%%a")

echo.

<nul set /p="("
call :PainText 09 "BLUE is cold"    && <nul set /p=")  ("
call :PainText 02 "GREEN is earth"  && <nul set /p=")  ("
call :PainText F0 "BLACK is night"  && <nul set /p=")"
echo.
<nul set /p="("
call :PainText 04 "RED is blood"    && <nul set /p=")  ("
call :PainText 0e "YELLOW is pee"   && <nul set /p=")  ("
call :PainText 0F "WHITE all colors"&& <nul set /p=")"

goto :end

:PainText
<nul set /p "=%DEL%" > "%~2"
findstr /v /a:%1 /R "+" "%~2" nul
del "%~2" > nul
goto :eof

:end
echo.
pause

5

Istnieje już zaakceptowana odpowiedź z ponad 250 głosami pozytywnymi. Przyczyną, dla której wciąż uczestniczę, jest to, że escapeznaki wymagane do echa nie są akceptowane przez wielu redaktorów (używam np. MS Code), a wszystkie inne rozwiązania wymagają oprogramowania innych firm (inne niż domyślne).

Obejście z użyciem tylko prostych poleceń wsadowych jest używane PROMPTzamiast ECHO. PROMPTPolecenie przyjmuje escapepostać w sposób dowolny-editor przyjazne jako $Esekwencję znaków. (Wystarczy wymienić Escw kodach ASCII ewakuacyjne ) z $E.

Oto kod demonstracyjny:

@ECHO OFF

    :: Do not pollute environment with the %prompt.bak% variable
    :: ! forgetting ENDLOCAL at the end of the batch leads to prompt corruption
    SETLOCAL

    :: Old prompt settings backup
    SET prompt.bak=%PROMPT%

    :: Entering the "ECHO"-like section

        :: Forcing prompt to display after every command (see below)
        ECHO ON

        :: Setting the prompt using the ANSI Escape sequence(s)
        :: - Always start with $E[1A, otherwise the text would appear on a next line
        :: - Then the decorated text follows
        :: - And it all ends with $E30;40m, which makes the following command invisible
        ::   - assuming default background color of the screen
        @ PROMPT $E[1A$E[30;42mHELLO$E[30;40m

        :: An "empty" command that forces the prompt to display. 
        :: The word "rem" is displayed along with the prompt text but is made invisible
        rem

        :: Just another text to display
        @ PROMPT $E[1A$E[33;41mWORLD$E[30;40m
        rem

        :: Leaving the "ECHO"-like section
        @ECHO OFF

    :: Or a more readable version utilizing the cursor manipulation ASCII ESC sequences

        :: the initial sequence
        PROMPT $E[1A
        :: formating commands
        PROMPT %PROMPT%$E[32;44m
        :: the text
        PROMPT %PROMPT%This is an "ECHO"ed text...
        :: new line; 2000 is to move to the left "a lot"
        PROMPT %PROMPT%$E[1B$E[2000D
        :: formating commands fro the next line
        PROMPT %PROMPT%$E[33;47m
        :: the text (new line)
        PROMPT %PROMPT%...spreading over two lines
        :: the closing sequence
        PROMPT %PROMPT%$E[30;40m

        :: Looks like this without the intermediate comments:
        :: PROMPT $E[1A
        :: PROMPT %PROMPT%$E[32;44m
        :: PROMPT %PROMPT%This is an "ECHO"ed text...
        :: PROMPT %PROMPT%$E[1B$E[2000D
        :: PROMPT %PROMPT%$E[33;47m
        :: PROMPT %PROMPT%...spreading over two lines
        :: PROMPT %PROMPT%$E[30;40m

        :: show it all at once!
        ECHO ON
        rem
        @ECHO OFF

    :: End of "ECHO"-ing

    :: Setting prompt back to its original value
    :: - We prepend the settings with $E[37;40m in case
    ::   the original prompt settings do not specify color
    ::   (as they don't by default).
    :: - If they do, the $E[37;40m will become overridden, anyway.
    :: ! It is important to write this command 
    ::   as it is with `ENDLOCAL` and in the `&` form.
    ENDLOCAL & PROMPT $E[37;40m%prompt.bak%

EXIT /B 0

UWAGA: Jedyną wadą jest to, że ta technika koliduje z ustawieniami kolorów cmd użytkownika ( colorpolecenie lub ustawienia), jeśli nie są wyraźnie znane.

- Mam nadzieję, że to pomaga, ponieważ jest to jedyne możliwe do przyjęcia rozwiązanie z powodów wymienionych na początku. -

EDYTOWAĆ:

W oparciu o komentarze dołączam kolejny fragment inspirowany @Jeb. To:

  • Pokazuje, jak uzyskać i używać środowiska wykonawczego znaków „Esc” (zamiast wprowadzania go do edytora) (rozwiązanie Jeba)
  • Używa „rodzimych” ECHOpoleceń
  • Nie wpływa to więc na PROMPTwartość lokalną
  • Pokazuje, że zabarwienie ECHOwydruku nieuchronnie wpływa na PROMPTkolor, więc i tak trzeba zresetować kolor
@ECHO OFF

    :: ! To observe color effects on prompt below in this script
    ::   run the script from a fresh cmd window with no custom
    ::   prompt settings

    :: Only not to pollute the environment with the %\e% variable (see below)
    :: Not needed because of the `PROMPT` variable
    SETLOCAL

        :: Parsing the `escape` character (ASCII 27) to a %\e% variable
        :: Use %\e% in place of `Esc` in the [http://ascii-table.com/ansi-escape-sequences.php]
        FOR /F "delims=#" %%E IN ('"prompt #$E# & FOR %%E IN (1) DO rem"') DO SET "\e=%%E"

        :: Demonstrate that prompt did not get corrupted by the previous FOR
        ECHO ON
        rem : After for
        @ECHO OFF

        :: Some fancy ASCII ESC staff
        ECHO [          ]
        FOR /L %%G IN (1,1,10) DO (
            TIMEOUT /T 1 > NUL
            ECHO %\e%[1A%\e%[%%GC%\e%[31;43m.
            ECHO %\e%[1A%\e%[11C%\e%[37;40m]
        )

        :: ECHO another decorated text
        :: - notice the `%\e%[30C` cursor positioning sequence
        ::   for the sake of the "After ECHO" test below
        ECHO %\e%[1A%\e%[13C%\e%[32;47mHELLO WORLD%\e%[30C

        :: Demonstrate that prompt did not get corrupted by ECHOing
        :: neither does the cursor positioning take effect.
        :: ! But the color settings do.
        ECHO ON
        rem : After ECHO
        @ECHO OFF

    ENDLOCAL

    :: Demonstrate that color settings do not reset
    :: even when out of the SETLOCAL scope
    ECHO ON
    rem : After ENDLOCAL
    @ECHO OFF

    :: Reset the `PROMPT` color
    :: - `PROMPT` itself is untouched so we did not need to backup it.
    :: - Still ECHOING in color apparently collide with user color cmd settings (if any).
    :: ! Resetting `PROMPT` color this way extends the `PROMPT`
    ::   by the initial `$E[37;40m` sequence every time the script runs.
    :: - Better solution then would be to end every (or last) `ECHO` command
    ::   with the `%\e%[37;40m` sequence and avoid setting `PROMPT` altogether.
    ::   which makes this technique preferable to the previous one (before EDIT)
    :: - I am keeping it this way only to be able to
    ::   demonstrate the `ECHO` color effects on the `PROMPT` above.
    PROMPT $E[37;40m%PROMPT%

    ECHO ON
    rem : After PROMPT color reset
    @ECHO OFF

EXIT /B 0

Bardzo interesująca technika. Zobaczę, czy muszę zaktualizować github.com/VonC/batcolors . Pozytywne.
VonC

@VonC Możesz po prostu utworzyć zmienną zawierającą znak ucieczki bez potrzeby wprowadzania jej do edytora. for /F "delims=#" %%E in ('"prompt #$E# & for %%E in (1) do rem"') do set "\e=%%E"
jeb

@jeb Czy masz na myśli „w przeciwieństwie do echoużywanych w batcolours / echo.bat ”?
VonC

@VonC Tak, wymienić set ASCII27=←z for /F "delims=#" %%E in ('"prompt #$E# & for %%E in (1) do rem"') do set "ASCII27=%%E". Wykorzystuje to znak zmiany znaczenia utworzony przez polecenie zachęty, bez zmiany pytania na stałe (ponieważ promptpolecenie jest wykonywane w procesie potomnym). Btw. Twój echos.batpotencjał optymalizacji ...
jeb

@jeb „Twój echos.bat ma pewien potencjał optymalizacji”: Jestem tego pewien :) Żądania ściągania są mile widziane (zarówno dla ASCII27, jak i innych optymalizacji)
VonC

4

Dodaję odpowiedź, aby rozwiązać problem zauważony w niektórych komentarzach powyżej: te kody kolorów Inline mogą źle zachowywać się w pętli FOR (w rzeczywistości w dowolnym bloku kodu w nawiasach). Poniższy kod .bat pokazuje (1) użycie wbudowanych kodów kolorów, (2) awarię kolorów, która może wystąpić, gdy wbudowane kody kolorów są używane w pętli FOR lub w nawiasowym bloku kodu, oraz (3) rozwiązanie problem. Po uruchomieniu kodu .bat testy 2 i 3 wykazują awarię kodu koloru, a test 4 nie wykazuje awarii, ponieważ implementuje rozwiązanie.

[EDIT 2020-04-07: Znalazłem inne rozwiązanie, które jest prawdopodobnie bardziej wydajne niż wywołanie podprogramu. Umieść frazę FINDSTR w nawiasach, jak w następującym wierszu:

   echo success | (findstr /R success)

ENDEDIT]

Uwaga: Z mojego (ograniczonego) doświadczenia problem z kodem koloru objawia się dopiero po przesłaniu danych wejściowych do FINDSTR wewnątrz bloku kodu. W ten sposób następujący .bat odtwarza problem. Możliwe, że problem z kodem koloru jest bardziej ogólny niż po instalacji w FINDSTR. Jeśli ktoś może wyjaśnić naturę problemu i jest lepszy sposób na jego rozwiązanie, byłbym wdzięczny.

@goto :main
:resetANSI
EXIT /B
rem  The resetANSI subroutine is used to fix the colorcode
rem  bug, even though it appears to do nothing.

:main
@echo off
setlocal EnableDelayedExpansion

rem  Define some useful colorcode vars:
for /F "delims=#" %%E in ('"prompt #$E# & for %%E in (1) do rem"') do set "ESCchar=%%E"
set "green=%ESCchar%[92m"
set "yellow=%ESCchar%[93m"
set "magenta=%ESCchar%[95m"
set "cyan=%ESCchar%[96m"
set "white=%ESCchar%[97m"
set "black=%ESCchar%[30m"

echo %white%Test 1 is NOT in a FOR loop nor within parentheses, and color works right.
   echo %yellow%[Test 1] %green%This is Green, %magenta%this is Magenta, and %yellow%this is Yellow.
   echo %Next, the string 'success' will be piped to FINDSTR...
   echo success | findstr /R success
   echo %magenta%This is magenta and FINDSTR found and displayed 'success'.%yellow%
   echo %green%This is green.
echo %cyan%Test 1 completed.

echo %white%Test 2 is within parentheses, and color stops working after the pipe to FINDSTR.
(  echo %yellow%[Test 2] %green%This is Green, %magenta%this is Magenta, and %yellow%this is Yellow.
   echo %Next, the string 'success' will be piped to FINDSTR...
   echo success | findstr /R success
   echo %magenta%This is supposed to be magenta and FINDSTR found and displayed 'success'.
   echo %green%This is supposed to be green.
)
echo %cyan%Test 2 completed.

echo %white%Test 3 is within a FOR loop, and color stops working after the pipe to FINDSTR.
for /L %%G in (3,1,3) do (
   echo %yellow%[Test %%G] %green%This is Green, %magenta%this is Magenta, and %yellow%this is Yellow.
   echo %Next, the string 'success' will be piped to FINDSTR...
   echo success | findstr /R success
   echo %magenta%This is supposed to be magenta and FINDSTR found and displayed 'success'.
   echo %green%This is supposed to be green.
)
echo %cyan%Test 3 completed.

echo %white%Test 4 is in a FOR loop but color works right because subroutine :resetANSI is 
echo called after the pipe to FINDSTR, before the next color code is used.
for /L %%G in (4,1,4) do (
   echo %yellow%[Test %%G] %green%This is Green, %magenta%this is Magenta, and %yellow%this is Yellow.
   echo %Next, the string 'success' will be piped to FINDSTR...
   echo success | findstr /R success
   call :resetANSI
   echo %magenta%This is magenta and FINDSTR found and displayed 'success'.
   echo %green%This is green.
)
echo %cyan%Test 4 completed.%white%

EXIT /B


1

Właśnie przekonwertowałem z Win 7 Home na Win 10 Pro i chciałem zastąpić partię, do której dzwonię z innych partii, aby wyświetlić echo informacji w kolorze. Przeglądając to, co omówiono powyżej, używam następujących, które bezpośrednio zastąpią moją poprzednią partię. UWAGA dodanie do wiadomości „~”, aby można było używać wiadomości ze spacjami. Zamiast zapamiętywać kody, używam liter dla potrzebnych kolorów.

Jeśli% 2 zawiera spacje, wymaga „...”% 1 Mocne kolory na czarnym tle: R = Czerwony G = ZIELONY Y = ŻÓŁTY W = BIAŁY

ECHO OFF
IF "%1"=="R" ECHO ^[91m%~2[0m
IF "%1"=="G" ECHO ^[92m%~2[0m
IF "%1"=="Y" ECHO ^[93m%~2[0m
IF "%1"=="W" ECHO ^[97m%~2[0m

0

Musisz zmienić sekwencję kodu ucieczki ANSI, aby zmienić kolor tekstu: http://en.wikipedia.org/wiki/ANSI_escape_code

Innym bardzo dobrym źródłem tych kodów ucieczki jest http://ascii-table.com/ansi-escape-sequences.php


Wygląda to naprawdę obiecująco, ale jak mogę wysłać znak Escape - ASCII 27 w poleceniu echa?
rui

10
Konsola Windows nie jest emulatorem terminala. Sekwencje specjalne ANSI po prostu nie działają. Możesz nakłonić Windows 9x do zrobienia tego, ładując ANSI.SYS, ale do tej pory mamy już za sobą.
Joey,

0

Umieść następujące wiersze w pliku o nazwie ColourText.basna pulpicie.

Imports System
Imports System.IO
Imports System.Runtime.InteropServices
Imports Microsoft.Win32

Public Module MyApplication  
Public Declare Function GetStdHandle Lib "kernel32" Alias "GetStdHandle" (ByVal nStdHandle As Long) As Long
Public Declare Function SetConsoleTextAttribute Lib "kernel32" Alias "SetConsoleTextAttribute" (ByVal hConsoleOutput As Long, ByVal wAttributes As Long) As Long
Public Const STD_ERROR_HANDLE = -12&
Public Const STD_INPUT_HANDLE = -10&
Public Const STD_OUTPUT_HANDLE = -11&

Sub Main()
    Dim hOut as Long
    Dim Ret as Long
    Dim Colour As Long
    Dim Colour1 As Long
    Dim Text As String
    hOut  = GetStdHandle(STD_OUTPUT_HANDLE)
    Colour = CLng("&h" & Split(Command(), " ")(0))
    Colour1 = Clng("&h" & Split(Command(), " ")(1))
    Text = Mid(Command(), 7)
    Ret = SetConsoleTextAttribute(hOut,  Colour)
    Console.Out.WriteLine(text)
    Ret = SetConsoleTextAttribute(hOut, Colour1)
End Sub
End Module

Zapisz go i wpisz następujące polecenie w wierszu polecenia.

"C:\Windows\Microsoft.NET\Framework\v4.0.30319\vbc.exe" /target:exe /out:"%userprofile%\desktop\ColourText.exe" "%userprofile%\desktop\ColourText.bas" /verbose

Plik o nazwie ColourText.exe pojawi się na pulpicie. Przenieś go do folderu Windows .

Aby użyć, musisz użyć dwóch kodów znaków, aby ustawić kolor, np . 01Nie 1.

ColourText ColourOfText ColourOfTextWhenFinished Text

EG Aby ustawić kolor niebieski na białym, nie przekazując żadnego tekstu, a następnie kolor czerwony na białym, kończąc na kolorze niebieskim na szarym.

ColourText F1 F1
ColourText F2 71 This is green on white

lub

ColourText F1 F1
cls
ColourText F4 F4
Echo Hello
Echo Hello today
ColourText F1 F1

CLSCiekawe staje się także polecenie. Colorpolecenie bez parametrów resetuje wszystkie kolory do kolorów początkowych.

Aby uzyskać kod koloru, dodaj następujące liczby razem. Użyj kalkulatora w trybie programisty. To są liczby szesnastkowe. Można je dodawać razem, np. Czerwony + niebieski + intensywność FG = 13 = D. Ponieważ 10+ nie zostało użyte, tło będzie czarne. Kody kolorów MUSZĄ składać się z dwóch znaków, np . 08Nie 8.

FOREGROUND_RED = &H4     '  text color contains red.
FOREGROUND_INTENSITY = &H8     '  text color is intensified.
FOREGROUND_GREEN = &H2     '  text color contains green.
FOREGROUND_BLUE = &H1     '  text color contains blue.
BACKGROUND_BLUE = &H10    '  background color contains blue.
BACKGROUND_GREEN = &H20    '  background color contains green.
BACKGROUND_INTENSITY = &H80    '  background color is intensified.
BACKGROUND_RED = &H40    '  background color contains red.

2
Chociaż interesujące, nie wszyscy będą mieć zainstalowany zestaw SDK, tak naprawdę, myślę, że bardzo mało osób.
Abel

0

Aby uzyskać tej pracy w systemie Windows 10, można włączyć tę flagę: ENABLE_VIRTUAL_TERMINAL_PROCESSING.

Za pomocą tego klucza rejestru można to ustawić domyślnie

[HKCU\Console] VirtualTerminalLevel dword 0x1


0

Alternatywą jest użycie NodeJS .

Oto przykład:

const os = require('os');
const colors = require('colors');

console.log("Operative System:".green,os.type(),os.release());
console.log("Uptime:".blue,os.uptime());

I to jest wynik:

wprowadź opis zdjęcia tutaj


0

Jak powiedział Glenn Slayden w tej odpowiedzi , możesz dodać do rejestru odpowiednią wartość, aby cmd był „bardziej kolorowy”.

Na szczęście globalne ustawienie domyślne można zmienić z opcji opt-in na opt-out. Klucz rejestru w HKEY_CURRENT_USER \ Console \ VirtualTerminalLevel ustawia globalne domyślne zachowanie przetwarzania sekwencji specjalnych ANSI. Utwórz klucz DWORD (jeśli to konieczne) i ustaw jego wartość na 1, aby domyślnie włączyć globalnie (lub 0, aby wyłączyć`) przetwarzanie ANSI.


0

Nadawanie kolorom instrukcji dziennika w PowerShell nie jest wielkim przyjacielem. możesz użyć -ForegroundColorparametru.

Aby napisać wiadomość potwierdzającą.

Write-Host "Process executed Successfully...." -ForegroundColor Magenta

Aby napisać komunikat o błędzie.

Write-Host "Sorry an unexpected error occurred.." -ForegroundColor Red

Aby napisać komunikat o postępie .

Write-Host "Working under pocess..." -ForegroundColor Green

0
call :color_echo "blue" "blue txt"
call :color_echo "red" "red txt"
echo "white txt"


REM : https://www.robvanderwoude.com/ansi.php
:color_echo
    @echo off

    set "color=%~1"
    set "txt=%~2"

    set ESC=
    set black=%ESC%[30m
    set red=%ESC%[31m
    set green=%ESC%[32m
    set yellow=%ESC%[33m
    set blue=%ESC%[34m
    set magenta=%ESC%[35m
    set cyan=%ESC%[36m
    set white=%ESC%[37m

    if "%~1" == "black"   set "color=!black!"
    if "%~1" == "red"     set "color=!red!"
    if "%~1" == "green"   set "color=!green!"
    if "%~1" == "yellow"  set "color=!yellow!"
    if "%~1" == "blue"    set "color=!blue!"
    if "%~1" == "magenta" set "color=!magenta!"
    if "%~1" == "cyan"    set "color=!cyan!"
    if "%~1" == "white"   set "color=!white!"

    echo | set /p="!color!!txt!"
    echo.

    REM : return to standard white color
    echo | set /p="!white!"

    REM : exiting the function only
    EXIT /B 0

%ESC%jest pusty, więc to nie zadziała. echo !white!ustawia kolor na biały. Aby powrócić do domyślnych kolorów (bez względu na ustawienia użytkownika): colorpolecenie bez parametrów to robi.
Stephan

-1

Robiliśmy to z kodami terminali ANSI . Nie jestem pewien, czy nadal działają, ale możesz je wypróbować.


1
To może być dobra odpowiedź, jeśli wyjaśni, jak korzystać z tych kodów terminali ANSI ...
Davor Josipovic

1
Myślałem, że artykuł, do którego linkuję, wyjaśnił to. Czytałeś to? BTW: mówi, że nie działają na Win32.
Michael J

Po przekątnej. W artykule wyjaśniono, jakie są kody terminali ANSI, ale nie bardzo, jak ich używać z poziomu cmd, aby odpowiedzieć na pytanie. (Tak ... fakt, że konsola Win32 nie jest obsługiwana, czyni je trochę nieistotnymi dla pytania.)
Davor Josipovic

1
Po prostu powtórzyłbyś kody ANSI do terminala. np. „echo ← [6m” ustawi kolor tekstu terminala na 6 (czerwony). Uwaga „←” to ASCII 27 (ucieczka). Możesz go wpisać, przytrzymując klawisz „ALT” i wpisując „27” na klawiaturze numerycznej. Właśnie go przejrzałem i odkryłem, że nadal możesz użyć polecenia „kolor”, aby zrobić to samo (chociaż kody numeryczne są różne). „kolor 4” daje ci czerwony tekst.
Michael J

-6

Możesz użyć polecenia koloru, aby zmienić kolor całej konsoli

Color 0F

Jest czarno-biały

Color 0A 

Jest czarno-zielony


20
Dobrze wiedzieć. Niestety zmienia to kolor całej konsoli, a pytanie brzmi: jak zmienić pojedynczą linię (lub jej część) ..
Luke

6
OP stwierdził, że zna to polecenie i problem polega na tym, że zmienia on całą konsolę, a nie konkretną linię.
Randall Flagg

5
Tak, tak naprawdę nie reaguje, ale nadal warto o tym wiedzieć.
CuriousMarc,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.