Как иметь несколько цветов в пакетном файле Windows?

Мне было интересно, возможно ли иметь другой цветной текст в одной строке в пакетном файле Windows, например, если он говорит

echo hi world

Я хочу, чтобы "привет" был одним цветом, а "мир" - другим цветом. Возможно, я мог бы установить команду COLOR в качестве переменной:

set color1= color 2
set color9= color A

а затем разверните их как на одной строке, так и на

echo hi world

но я не знаю, как это сделать.

Ответ 1

На самом деле это можно сделать без создания временного файла. Метод, описанный jeb и dbenham, будет работать даже с целевым файлом, который не содержит обратных пространств. Критической точкой является то, что строка, распознаваемая findstr.exe, не должна заканчиваться CRLF. Таким образом, очевидный текстовый файл для сканирования с линией, не заканчивающейся CRLF, является самой вызывающей партией, при условии, что мы заканчиваем ее такой строкой! Здесь обновленный пример script работает таким образом...

Изменения в предыдущем примере:

  • Использует одну тире в последней строке в качестве строки с возможностью поиска. (Должен быть коротким и не встречаться нигде в этом пакете.)
  • Переименованные подпрограммы и переменные будут немного более объектно-ориентированными: -)
  • Удален один уровень вызова, чтобы немного повысить производительность.
  • Добавленные комментарии (Начиная с: #, чтобы больше походить на большинство других языков сценариев.)

@echo off
setlocal

call :Echo.Color.Init

goto main

:Echo.Color %1=Color %2=Str [%3=/n]
setlocal enableDelayedExpansion
set "str=%~2"
:Echo.Color.2
:# Replace path separators in the string, so that the final path still refers to the current path.
set "str=a%ECHO.DEL%!str:\=a%ECHO.DEL%\..\%ECHO.DEL%%ECHO.DEL%%ECHO.DEL%!"
set "str=!str:/=a%ECHO.DEL%/..\%ECHO.DEL%%ECHO.DEL%%ECHO.DEL%!"
set "str=!str:"=\"!"
:# Go to the script directory and search for the trailing -
pushd "%ECHO.DIR%"
findstr /p /r /a:%~1 "^^-" "!str!\..\!ECHO.FILE!" nul
popd
:# Remove the name of this script from the output. (Dependant on its length.)
for /l %%n in (1,1,12) do if not "!ECHO.FILE:~%%n!"=="" <nul set /p "=%ECHO.DEL%"
:# Remove the other unwanted characters "\..\: -"
<nul set /p "=%ECHO.DEL%%ECHO.DEL%%ECHO.DEL%%ECHO.DEL%%ECHO.DEL%%ECHO.DEL%%ECHO.DEL%"
:# Append the optional CRLF
if not "%~3"=="" echo.
endlocal & goto :eof

:Echo.Color.Var %1=Color %2=StrVar [%3=/n]
if not defined %~2 goto :eof
setlocal enableDelayedExpansion
set "str=!%~2!"
goto :Echo.Color.2

:Echo.Color.Init
set "ECHO.COLOR=call :Echo.Color"
set "ECHO.DIR=%~dp0"
set "ECHO.FILE=%~nx0"
set "ECHO.FULL=%ECHO.DIR%%ECHO.FILE%"
:# Use prompt to store a backspace into a variable. (Actually backspace+space+backspace)
for /F "tokens=1 delims=#" %%a in ('"prompt #$H# & echo on & for %%b in (1) do rem"') do set "ECHO.DEL=%%a"
goto :eof

:main
call :Echo.Color 0a "a"
call :Echo.Color 0b "b"
set "txt=^" & call :Echo.Color.Var 0c txt
call :Echo.Color 0d "<"
call :Echo.Color 0e ">"
call :Echo.Color 0f "&"
call :Echo.Color 1a "|"
call :Echo.Color 1b " "
call :Echo.Color 1c "%%%%"
call :Echo.Color 1d ^"""
call :Echo.Color 1e "*"
call :Echo.Color 1f "?"
:# call :Echo.Color 2a "!"
call :Echo.Color 2b "."
call :Echo.Color 2c ".."
call :Echo.Color 2d "/"
call :Echo.Color 2e "\"
call :Echo.Color 2f "q:" /n
echo(
set complex="c:\hello world!/.\..\\a//^<%%>&|!" /^^^<%%^>^&^|!\
call :Echo.Color.Var 74 complex /n

exit /b

:# The following line must be last and not end by a CRLF.
-

PS. У меня проблема с выходом! характер, которого у вас не было в предыдущем примере. (Или, по крайней мере, у вас не было таких же симптомов.) Для исследования.

Ответ 2

Вы можете делать многоцветные выходы без каких-либо внешних программ.

@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"
)
echo say the name of the colors, don't read

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

goto :eof

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

Он использует функцию цвета команды findstr.

Findstr может быть настроен для вывода номеров строк или имен файлов в определенном цвете.
Поэтому я сначала создаю файл с текстом в качестве имени файла, а содержимое представляет собой один символ <backspace> (ASCII 8).
Затем я просматриваю все непустые строки в файле и в nul, поэтому имя файла будет выводиться в правильном цвете, добавленном двоеточием, но двоеточие немедленно удаляется с помощью <backspace>.

EDIT: через год... все символы действительны

@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"
)

rem Prepare a file "X" with only one dot
<nul > X set /p ".=."

call :color 1a "a"
call :color 1b "b"
call :color 1c "^!<>&| %%%%"*?"
exit /b

:color
set "param=^%~2" !
set "param=!param:"=\"!"
findstr /p /A:%1 "." "!param!\..\X" nul
<nul set /p ".=%DEL%%DEL%%DEL%%DEL%%DEL%%DEL%%DEL%"
exit /b

Здесь используется правило для допустимого пути/имени файла.
Если a \..\ находится в пути, префикс elemet будет удален полностью, и нет необходимости, чтобы этот элемент содержал только допустимые имена файлов.

Ответ 3

Редактированный ответ jeb близок к решению всех проблем. Но у него есть проблемы со следующими строками:

"a\b\"
"a/b/"
"\"
"/"
"."
".."
"c:"

Я изменил его технику на то, что, по-моему, действительно может обрабатывать любую строку печатных символов, за исключением ограничений по длине.

Другие улучшения:

  • Использует место% TEMP% для временного файла, поэтому вам больше не нужен доступ на запись к текущему каталогу.

  • Создано 2 варианта, один принимает строковый литерал, другой - имя переменной, содержащей строку. Переменная версия, как правило, менее удобна, но устраняет некоторые особые проблемы с экранами.

  • Добавлена опция /n в качестве необязательного третьего параметра для добавления новой строки в конце вывода.

Backspace не работает во время разрыва строки, поэтому техника может иметь проблемы, если линия обертывается. Например, печать строки длиной от 74 до 79 не будет работать должным образом, если консоль имеет ширину линии 80.

@echo off
setlocal

call :initColorPrint

call :colorPrint 0a "a"
call :colorPrint 0b "b"
set "txt=^" & call :colorPrintVar 0c txt
call :colorPrint 0d "<"
call :colorPrint 0e ">"
call :colorPrint 0f "&"
call :colorPrint 1a "|"
call :colorPrint 1b " "
call :colorPrint 1c "%%%%"
call :colorPrint 1d ^"""
call :colorPrint 1e "*"
call :colorPrint 1f "?"
call :colorPrint 2a "!"
call :colorPrint 2b "."
call :colorPrint 2c ".."
call :colorPrint 2d "/"
call :colorPrint 2e "\"
call :colorPrint 2f "q:" /n
echo(
set complex="c:\hello world!/.\..\\a//^<%%>&|!" /^^^<%%^>^&^|!\
call :colorPrintVar 74 complex /n

call :cleanupColorPrint

exit /b

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

:colorPrint Color  Str  [/n]
setlocal
set "str=%~2"
call :colorPrintVar %1 str %3
exit /b

:colorPrintVar  Color  StrVar  [/n]
if not defined %~2 exit /b
setlocal enableDelayedExpansion
set "str=a%DEL%!%~2:\=a%DEL%\..\%DEL%%DEL%%DEL%!"
set "str=!str:/=a%DEL%/..\%DEL%%DEL%%DEL%!"
set "str=!str:"=\"!"
pushd "%temp%"
findstr /p /A:%1 "." "!str!\..\x" nul
if /i "%~3"=="/n" echo(
exit /b

:initColorPrint
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do set "DEL=%%a"
<nul >"%temp%\x" set /p "=%DEL%%DEL%%DEL%%DEL%%DEL%%DEL%.%DEL%"
exit /b

:cleanupColorPrint
del "%temp%\x"
exit /b


ОБНОВЛЕНИЕ 2012-11-27

Этот метод терпит неудачу в XP, потому что FINDSTR отображает обратное пространство как период на экране. jeb оригинальный ответ работает на XP, хотя с уже отмеченными ограничениями


ОБНОВЛЕНИЕ 2012-12-14

В DosTips и SS64 было много разработок. Оказывается, FINDSTR также повреждает имена файлов, содержащие расширенный ASCII, если они указаны в командной строке. Я обновил вопросы и ответы FINDSTR.

Ниже приведена версия, которая работает на XP и поддерживает ВСЕ одиночные байтовые символы, кроме 0x00 (nul), 0x0A (linefeed) и 0x0D (возврат каретки). Однако при работе на XP большинство управляющих символов будут отображаться в виде точек. Это неотъемлемая особенность FINDSTR на XP, чего нельзя избежать.

К сожалению, добавление поддержки XP и расширенных символов ASCII замедляет процедуру вниз :-(

Просто для удовольствия я схватил некоторое искусство ASCII от художественной галереи AANII от Joan Stark и адаптировал его для использования с ColorPrint. Я добавил точку входа: c только для сокращений и для обработки проблемы с литералами цитат.

@echo off
setlocal disableDelayedExpansion
set q=^"
echo(
echo(
call :c 0E "                ,      .-;" /n
call :c 0E "             ,  |\    / /  __," /n
call :c 0E "             |\ '.'-.|  |.'.-'" /n
call :c 0E "              \''-:  '; : /" /n
call :c 0E "               '-._'.  \'|" /n
call :c 0E "              ,_.-=' ' '  ~,_" /n
call :c 0E "               '--,.    "&call :c 0c ".-. "&call :c 0E ",=!q!." /n
call :c 0E "                 /     "&call :c 0c "{ "&call :c 0A "* "&call :c 0c ")"&call :c 0E "'"&call :c 06 ";-."&call :c 0E "}" /n
call :c 0E "                 |      "&call :c 0c "'-' "&call :c 06 "/__ |" /n
call :c 0E "                 /          "&call :c 06 "\_,\|" /n
call :c 0E "                 |          (" /n
call :c 0E "             "&call :c 0c "__ "&call :c 0E "/ '          \" /n
call :c 02 "     /\_    "&call :c 0c "/,''"&call :c 0E "|     '   "&call :c 0c ".-~!q!~~-." /n
call :c 02 "     |'.\_ "&call :c 0c "|   "&call :c 0E "/  ' ,    "&call :c 0c "/        \" /n
call :c 02 "   _/  ', \"&call :c 0c "|  "&call :c 0E "; ,     . "&call :c 0c "|  ,  '  . |" /n
call :c 02 "   \   ',  "&call :c 0c "|  "&call :c 0E "|  ,  ,   "&call :c 0c "|  :  ;  : |" /n
call :c 02 "   _\  ',  "&call :c 0c "\  "&call :c 0E "|.     ,  "&call :c 0c "|  |  |  | |" /n
call :c 02 "   \'  '.   "&call :c 0c "\ "&call :c 0E "|   '     "&call :c 0A "|"&call :c 0c "\_|-'|_,'\|" /n
call :c 02 "   _\   ',   "&call :c 0A "'"&call :c 0E "\  '  . ' "&call :c 0A "| |  | |  |           "&call :c 02 "__" /n
call :c 02 "   \     ',   "&call :c 0E "| ,  '    "&call :c 0A "|_/'-|_\_/     "&call :c 02 "__ ,-;' /" /n
call :c 02 "    \    ',    "&call :c 0E "\ .  , ' .| | | | |   "&call :c 02 "_/' ' _='|" /n
call :c 02 "     '\    ',   "&call :c 0E "\     ,  | | | | |"&call :c 02 "_/'   .=!q!  /" /n
call :c 02 "     \'     ',   "&call :c 0E "'\      \/|,| ;"&call :c 02 "/'   .=!q!    |" /n
call :c 02 "      \      ',    "&call :c 0E "'\' ,  | ; "&call :c 02 "/'    =!q!    _/" /n
call :c 02 "       '\     ',  "&call :c 05 ".-!q!!q!-. "&call :c 0E "': "&call :c 02 "/'    =!q!     /" /n
call :c 02 "    jgs _'\    ;"&call :c 05 "_{  '   ; "&call :c 02 "/'    =!q!      /" /n
call :c 02 "       _\'-/__"&call :c 05 ".~  '."&call :c 07 "8"&call :c 05 ".'.!q!'~-. "&call :c 02 "=!q!     _,/" /n
call :c 02 "    __\      "&call :c 05 "{   '-."&call :c 07 "|"&call :c 05 ".'.--~''}"&call :c 02 "    _/" /n
call :c 02 "    \    .=!q!' "&call :c 05 "}.-~!q!'"&call :c 0D "u"&call :c 05 "'-. '-..'  "&call :c 02 "__/" /n
call :c 02 "   _/  .!q!    "&call :c 05 "{  -'.~('-._,.'"&call :c 02 "\_,/" /n
call :c 02 "  /  .!q!    _/'"&call :c 05 "'--; ;  '.  ;" /n
call :c 02 "   .=!q!  _/'      "&call :c 05 "'-..__,-'" /n
call :c 02 "    __/'" /n
echo(

exit /b

:c
setlocal enableDelayedExpansion
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

:colorPrint Color  Str  [/n]
setlocal
set "s=%~2"
call :colorPrintVar %1 s %3
exit /b

:colorPrintVar  Color  StrVar  [/n]
if not defined DEL call :initColorPrint
setlocal enableDelayedExpansion
pushd .
':
cd \
set "s=!%~2!"
:: The single blank line within the following IN() clause is critical - DO NOT REMOVE
for %%n in (^"^

^") do (
  set "s=!s:\=%%~n\%%~n!"
  set "s=!s:/=%%~n/%%~n!"
  set "s=!s::=%%~n:%%~n!"
)
for /f delims^=^ eol^= %%s in ("!s!") do (
  if "!" equ "" setlocal disableDelayedExpansion
  if %%s==\ (
    findstr /a:%~1 "." "\'" nul
    <nul set /p "=%DEL%%DEL%%DEL%"
  ) else if %%s==/ (
    findstr /a:%~1 "." "/.\'" nul
    <nul set /p "=%DEL%%DEL%%DEL%%DEL%%DEL%"
  ) else (
    >colorPrint.txt (echo %%s\..\')
    findstr /a:%~1 /f:colorPrint.txt "."
    <nul set /p "=%DEL%%DEL%%DEL%%DEL%%DEL%%DEL%%DEL%"
  )
)
if /i "%~3"=="/n" echo(
popd
exit /b


:initColorPrint
for /f %%A in ('"prompt $H&for %%B in (1) do rem"') do set "DEL=%%A %%A"
<nul >"%temp%\'" set /p "=."
subst ': "%temp%" >nul
exit /b


:cleanupColorPrint
2>nul del "%temp%\'"
2>nul del "%temp%\colorPrint.txt"
>nul subst ': /d
exit /b

Ответ 4

Если у вас установлена ​​современная Windows (у которой установлена ​​PowerShell), то также может работать нормально

call :PrintBright Something Something

  (do actual batch stuff here)

call :PrintBright Done!
goto :eof


:PrintBright
powershell -Command Write-Host "%*" -foreground "White"

Отрегулируйте цвет по своему усмотрению.

Ответ 5

Без внешних инструментов. Это самокомпилированный гибрид bat/.net (должен быть сохранен как .BAT), которые можно использовать в любой системе, на которой установлена ​​.NET-инфраструктура (редко можно увидеть окна без платформы .NET даже для самых старых установок XP/2003). Он использует компилятор jscript.net для создания exe, способного печатать строки с различным цветом фона/переднего плана только для текущей строки.

@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;

Пример coloroutput.bat -s "aa\nbb\n\u0025cc" -b 10 -f 3 -n -e

Вы также можете проверить цветовую функцию carlos → http://www.dostips.com/forum/viewtopic.php?f=3&t=4453

Ответ 6

Для завершения этой темы вы также можете отображать текст в цвете с помощью моей вспомогательной программы ColorShow.exe; вы можете загрузить его из на этом сайте, ищите программу # 12. Обратите внимание, что первая часть документации отображается в программе №2-Show.exe.

На этом сайте есть несколько вспомогательных программ, которые позволяют достичь некоторых интересных вещей. Например, программа # 6-CursorPos.exe позволяет перемещать курсор в любое место на экране.

Это пример вывода, созданный пакетным файлом с использованием моей вспомогательной программы ColorShow.exe:

Mona-Lisa

Пакетный файл занял менее 3 секунд, чтобы отобразить предыдущее изображение, имеющее разрешение 322x138 (используя шрифт Lucida Console font @size 5). Вы можете просмотреть метод, используемый для создания этого изображения в этот пост.

EDIT. Я опубликовал гораздо более простой способ получить программу ColorShow.exe и краткое описание ее; просто следуйте этой ссылке.

Ответ 7

Объединяя птицу и синтаксис dbenham с помощью метода skrebbel powershell write-host, кажется, что powershell может отображать сложное искусство быстрее, чем простой пакетный метод dbenham (ну, после того, как PowerShell был загрунтован один раз, во всяком случае). Нужно минимальное массирование струн, хотя я не тестировал это ни с чем, кроме птицы. Если вам нужен яркий зеленый символ конца передачи, например, вам может быть не повезло. :)

Этот метод требует эхо-ответа на временный файл, просто потому, что вызов powershell для каждого call :c выполняется навсегда, и намного быстрее очередь на вывод для одного вызова powershell. Но это имеет преимущество простоты и эффективности.

@echo off
setlocal disableDelayedExpansion
set q=^"
echo(
echo(
call :c 0E "                ,      .-;" /n
call :c 0E "             ,  |\    / /  __," /n
call :c 0E "             |\ '.`-.|  |.'.-'" /n
call :c 0E "              \`'-:  `; : /" /n
call :c 0E "               `-._'.  \'|" /n
call :c 0E "              ,_.-=` ` `  ~,_" /n
call :c 0E "               '--,.    "&call :c 0c ".-. "&call :c 0E ",=!q!." /n
call :c 0E "                 /     "&call :c 0c "{ "&call :c 0A "* "&call :c 0c ")"&call :c 0E "`"&call :c 06 ";-."&call :c 0E "}" /n
call :c 0E "                 |      "&call :c 0c "'-' "&call :c 06 "/__ |" /n
call :c 0E "                 /          "&call :c 06 "\_,\|" /n
call :c 0E "                 |          (" /n
call :c 0E "             "&call :c 0c "__ "&call :c 0E "/ '          \" /n
call :c 02 "     /\_    "&call :c 0c "/,'`"&call :c 0E "|     '   "&call :c 0c ".-~!q!~~-." /n
call :c 02 "     |`.\_ "&call :c 0c "|   "&call :c 0E "/  ' ,    "&call :c 0c "/        \" /n
call :c 02 "   _/  `, \"&call :c 0c "|  "&call :c 0E "; ,     . "&call :c 0c "|  ,  '  . |" /n
call :c 02 "   \   `,  "&call :c 0c "|  "&call :c 0E "|  ,  ,   "&call :c 0c "|  :  ;  : |" /n
call :c 02 "   _\  `,  "&call :c 0c "\  "&call :c 0E "|.     ,  "&call :c 0c "|  |  |  | |" /n
call :c 02 "   \`  `.   "&call :c 0c "\ "&call :c 0E "|   '     "&call :c 0A "|"&call :c 0c "\_|-'|_,'\|" /n
call :c 02 "   _\   `,   "&call :c 0A "`"&call :c 0E "\  '  . ' "&call :c 0A "| |  | |  |           "&call :c 02 "__" /n
call :c 02 "   \     `,   "&call :c 0E "| ,  '    "&call :c 0A "|_/'-|_\_/     "&call :c 02 "__ ,-;` /" /n
call :c 02 "    \    `,    "&call :c 0E "\ .  , ' .| | | | |   "&call :c 02 "_/' ` _=`|" /n
call :c 02 "     `\    `,   "&call :c 0E "\     ,  | | | | |"&call :c 02 "_/'   .=!q!  /" /n
call :c 02 "     \`     `,   "&call :c 0E "`\      \/|,| ;"&call :c 02 "/'   .=!q!    |" /n
call :c 02 "      \      `,    "&call :c 0E "`\' ,  | ; "&call :c 02 "/'    =!q!    _/" /n
call :c 02 "       `\     `,  "&call :c 05 ".-!q!!q!-. "&call :c 0E "': "&call :c 02 "/'    =!q!     /" /n
call :c 02 "    jgs _`\    ;"&call :c 05 "_{  '   ; "&call :c 02 "/'    =!q!      /" /n
call :c 02 "       _\`-/__"&call :c 05 ".~  `."&call :c 07 "8"&call :c 05 ".'.!q!`~-. "&call :c 02 "=!q!     _,/" /n
call :c 02 "    __\      "&call :c 05 "{   '-."&call :c 07 "|"&call :c 05 ".'.--~'`}"&call :c 02 "    _/" /n
call :c 02 "    \    .=!q!` "&call :c 05 "}.-~!q!'"&call :c 0D "u"&call :c 05 "'-. '-..'  "&call :c 02 "__/" /n
call :c 02 "   _/  .!q!    "&call :c 05 "{  -'.~('-._,.'"&call :c 02 "\_,/" /n
call :c 02 "  /  .!q!    _/'"&call :c 05 "`--; ;  `.  ;" /n
call :c 02 "   .=!q!  _/'      "&call :c 05 "`-..__,-'" /n
call :c 02 "    __/'" /n

if exist "%temp%\color.psm1" (
    powershell -command "&{set-executionpolicy remotesigned; Import-Module '%temp%\color.psm1'}"
    del "%temp%\color.psm1"
)

echo(

exit /b

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

:c <color pair> <string> </n>
setlocal enabledelayedexpansion
set "colors=0-black;1-darkblue;2-darkgreen;3-darkcyan;4-darkred;5-darkmagenta;6-darkyellow;7-gray;8-darkgray;9-blue;a-green;b-cyan;c-red;d-magenta;e-yellow;f-white"
set "p=%~1"
set "bg=!colors:*%p:~0,1%-=!"
set bg=%bg:;=&rem.%
set "fg=!colors:*%p:~-1%-=!"
set fg=%fg:;=&rem.%

if not "%~3"=="/n" set "br=-nonewline"
set "str=%~2" & set "str=!str:'=''!"

>>"%temp%\color.psm1" echo write-host '!str!' -foregroundcolor '%fg%' -backgroundcolor '%bg%' %br%
endlocal

Результат:

enter image description here

Ответ 8

Да, возможно с cmdcolor:

echo \033[32mhi \033[92mworld

hi будет темно-зеленым, а world - светло-зеленым.

Ответ 9

Вы должны скачать chgcolor.zip из http://www.mailsend-online.com/blog/setting-text-color-in-a-batch-file.html а также загрузить echoj.zip из www.mailsend-online.com/blog/?p=41 Они оба направлены к нижней части страницы. Извлеките обе папки на рабочий стол и скопируйте исполняемые файлы (.exe файлы) из извлеченных папок в каталог C:\Windows. Это позволит выполнить их из командной строки. Откройте блокнот и скопируйте в него следующее:

@echo off

chgcolor 03

echoj "hi"

chgcolor 0d

echoj "world"

chgcolor 07

echoj $0a

Сохраните файл на рабочем столе как hi.bat. Теперь откройте командную строку и перейдите в папку "Рабочий стол" и введите "hi.bat" без кавычек. Это должно заставить вас начать читать оба веб-страницы, чтобы получить полный учебник.

Ответ 10

В приложении описаны несколько методов 51) Как я могу эхо-строки в разных цветах в сценариях NT? " http://www.netikka.net/tsneti/info/tscmd051.htm

Один из альтернатив: если вы можете получить QBASIC, использование цветов относительно просто:

  @echo off & setlocal enableextensions
  for /f "tokens=*" %%f in ("%temp%") do set temp_=%%~sf
  set skip=
  findstr "'%skip%QB" "%~f0" > %temp_%\tmp$$$.bas
  qbasic /run %temp_%\tmp$$$.bas
  for %%f in (%temp_%\tmp$$$.bas) do if exist %%f del %%f
  endlocal & goto :EOF
  ::
  CLS 'QB
  COLOR 14,0 'QB
  PRINT "A simple "; 'QB
  COLOR 13,0 'QB
  PRINT "color "; 'QB
  COLOR 14,0 'QB
  PRINT "demonstration" 'QB
  PRINT "By Prof. (emer.) Timo Salmi" 'QB
  PRINT 'QB
  FOR j = 0 TO 7 'QB
    FOR i = 0 TO 15 'QB
      COLOR i, j 'QB
      PRINT LTRIM$(STR$(i)); " "; LTRIM$(STR$(j)); 'QB
      COLOR 1, 0 'QB
      PRINT " "; 'QB
    NEXT i 'QB
    PRINT 'QB
  NEXT j 'QB
  SYSTEM 'QB

Ответ 11

Если вы не используете более старую операционную систему, я полагаю, что это невозможно сделать с доступными вам командами.

Однако все не потеряно, посмотрите на эту страницу:

http://www.mailsend-online.com/blog/setting-text-color-in-a-batch-file.html

Это даст вам именно то, что вам нужно, нижняя сторона - это то, что вам нужно добавить утилиты на эту страницу.

Ответ 12

Если ваша консоль поддерживает цветовые коды ANSI (например, ConEmu, Clink или ANSICON), вы можете сделать это:

SET    GRAY=%ESC%[0m
SET     RED=%ESC%[1;31m
SET   GREEN=%ESC%[1;32m
SET  ORANGE=%ESC%[0;33m
SET    BLUE=%ESC%[0;34m
SET MAGENTA=%ESC%[0;35m
SET    CYAN=%ESC%[1;36m
SET   WHITE=%ESC%[1;37m

где переменная ESC содержит символ ASCII 27.

Я нашел способ заполнить переменную ESC здесь: http://www.dostips.com/forum/viewtopic.php?p=6827#p6827 и используя tasklist, можно проверить, какие DLL загружаются в процесс.

Следующий script получает идентификатор процесса cmd.exe, в котором выполняется script. Проверяет, имеет ли он DLL, которая добавит добавленную поддержку ANSI, а затем устанавливает цветовые переменные, содержащие escape-последовательности или пуст в зависимости от того, поддерживается ли цвет или нет.

@echo off

call :INIT_COLORS

echo %RED%RED %GREEN%GREEN %ORANGE%ORANGE %BLUE%BLUE %MAGENTA%MAGENTA %CYAN%CYAN %WHITE%WHITE %GRAY%GRAY

:: pause if double clicked on instead of run from command line.
SET interactive=0
ECHO %CMDCMDLINE% | FINDSTR /L %COMSPEC% >NUL 2>&1
IF %ERRORLEVEL% == 0 SET interactive=1
@rem ECHO %CMDCMDLINE% %COMSPEC% %interactive%
IF "%interactive%"=="1" PAUSE
EXIT /B 0
Goto :EOF

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
: SUBROUTINES                                                          :
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

::::::::::::::::::::::::::::::::
:INIT_COLORS
::::::::::::::::::::::::::::::::

call :supportsANSI
if ERRORLEVEL 1 (
  SET GREEN=
  SET RED=
  SET GRAY=
  SET WHITE=
  SET ORANGE=
  SET CYAN=
) ELSE (

  :: If you can, insert ASCII CHAR 27 after equals and remove BL.String.CreateDEL_ESC routine
  set "ESC="
  :: use this if can't type ESC CHAR, it more verbose, but you can copy and paste it
  call :BL.String.CreateDEL_ESC

  SET    GRAY=%ESC%[0m
  SET     RED=%ESC%[1;31m
  SET   GREEN=%ESC%[1;32m
  SET  ORANGE=%ESC%[0;33m
  SET    BLUE=%ESC%[0;34m
  SET MAGENTA=%ESC%[0;35m
  SET    CYAN=%ESC%[1;36m
  SET   WHITE=%ESC%[1;37m
)

exit /b

::::::::::::::::::::::::::::::::
:BL.String.CreateDEL_ESC
::::::::::::::::::::::::::::::::
:: http://www.dostips.com/forum/viewtopic.php?t=1733
::
:: Creates two variables with one character DEL=Ascii-08 and ESC=Ascii-27
:: DEL and ESC can be used  with and without DelayedExpansion
setlocal
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
  ENDLOCAL
  set "DEL=%%a"
  set "ESC=%%b"
  goto :EOF
)

::::::::::::::::::::::::::::::::
:supportsANSI
::::::::::::::::::::::::::::::::
:: returns ERRORLEVEL 0 - YES, 1 - NO
::
:: - Tests for ConEmu, ANSICON and Clink
:: - Returns 1 - NO support, when called via "CMD /D" (i.e. no autoruns / DLL injection)
::   on a system that would otherwise support ANSI.

if "%ConEmuANSI%" == "ON" exit /b 0

call :getPID PID

setlocal

for /f usebackq^ delims^=^"^ tokens^=^* %%a in (`tasklist /fi "PID eq %PID%" /m /fo CSV`) do set "MODULES=%%a"

set MODULES=%MODULES:"=%
set NON_ANSI_MODULES=%MODULES%

:: strip out ANSI dlls from module list:
:: ANSICON adds ANSI64.dll or ANSI32.dll
set "NON_ANSI_MODULES=%NON_ANSI_MODULES:ANSI=%"
:: ConEmu attaches ConEmuHk but ConEmu also sets ConEmuANSI Environment VAR
:: so we've already checked for that above and returned early.
@rem set "NON_ANSI_MODULES=%NON_ANSI_MODULES:ConEmuHk=%"
:: Clink supports ANSI https://github.com/mridgers/clink/issues/54
set "NON_ANSI_MODULES=%NON_ANSI_MODULES:clink_dll=%"

if "%MODULES%" == "%NON_ANSI_MODULES%" endlocal & exit /b 1
endlocal

exit /b 0

::::::::::::::::::::::::::::::::
:getPID  [RtnVar]
::::::::::::::::::::::::::::::::
:: REQUIREMENTS:
::
:: Determine the Process ID of the currently executing script,
:: but in a way that is multiple execution safe especially when the script can be executing multiple times
::   - at the exact same time in the same millisecond,
::   - by multiple users,
::   - in multiple window sessions (RDP),
::   - by privileged and non-privileged (e.g. Administrator) accounts,
::   - interactively or in the background.
::   - work when the cmd.exe window cannot appear
::     e.g. running from TaskScheduler as LOCAL SERVICE or using the "Run whether user is logged on or not" setting
::
:: https://social.msdn.microsoft.com/Forums/vstudio/en-US/270f0842-963d-4ed9-b27d-27957628004c/what-is-the-pid-of-the-current-cmdexe?forum=msbuild
::
:: http://serverfault.com/a/654029/306
::
:: Store the Process ID (PID) of the currently running script in environment variable RtnVar.
:: If called without any argument, then simply write the PID to stdout.
::
::
setlocal disableDelayedExpansion
:getLock
set "lock=%temp%\%~nx0.%time::=.%.lock"
set "uid=%lock:\=:b%"
set "uid=%uid:,=:c%"
set "uid=%uid:'=:q%"
set "uid=%uid:_=:u%"
setlocal enableDelayedExpansion
set "uid=!uid:%%=:p!"
endlocal & set "uid=%uid%"
2>nul ( 9>"%lock%" (
  for /f "skip=1" %%A in (
    'wmic process where "name='cmd.exe' and CommandLine like '%%<%uid%>%%'" get ParentProcessID'
  ) do for %%B in (%%A) do set "PID=%%B"
  (call )
))||goto :getLock
del "%lock%" 2>nul
endlocal & if "%~1" equ "" (echo(%PID%) else set "%~1=%PID%"
exit /b

Ответ 13

Все альтернативы, описанные до сих пор, используют любые временные файлы. Это плохо, не всегда можно использовать временные файлы. Этот script ниже не использует временный файл и может писать текст на любом экране. Для этой цели лучшим script является this