Wie kann man in einer Batchdatei Text in zwei Farben anzeigen lassen?

2 Antworten

Vom Fragesteller als hilfreich ausgezeichnet

Ohne irgendwelche immensen Verrenkungen (wie Powershellaufrufe oder den Findstr-Trick) geht das nicht.

Dabei ist bei allen Tricksereien das Problem das diese durch den Aufruf eines Externen Programms zum Schreiben einer farbigen Zeile extrem Langsam sind.

Wenn du schon auf Powershell...

Write-Host 'Text' -fo 'blue' -ba 'red';

....zurückgreifen möchtest kannst Du besser das gesamte Projekt in dieser Sprache realisieren.

Batch ist eine AutomatisierungsSprache und muss keine hübschen Text anzeigen.

Wer etwas fürs Auge programmieren möchte ist bei Batch in der falsche Sprache gelandet...

Woher ich das weiß:eigene Erfahrung – Ich mach das seit 30 Jahren
Blackbanana33 
Fragesteller
 11.12.2019, 23:14

Okay, ich muss sagen Batch gefällt mir sonst sehr gut und das wäre zwar schön aber muss ja nicht sein. Aber vielen dank für die Antwort.

0
Erzesel  12.12.2019, 08:05
@Blackbanana33

Hier eine kleine eigene Demo mit einer JScript.Net-Batchhypride, welche eine exe on the Fly compiliert und diese für die Ausgabe von farbigen Text nutzt. (die xcolor.exe kannst Du auch nutzen ohne den Code in Deiner Batchdatei mitzugeben)

allerdings macht sich das ganze gut, wenn man die Batch weitergibt.

Dann gibt es keine Probleme mit exe aus unbekannter Quelle, da der Code ja vorliegt.

@if (@X)==(@Y) @end /* rem Batch als JScriptkommentar maskieren
@echo off
setlocal
  rem Compiler suchen
for /f "tokens=* delims=" %%v in ('dir /b /s /a:-d  /o:-n "%SystemRoot%\Microsoft.NET\Framework\*jsc.exe"') do (set "jsc=%%v")
  rem programm compilieren
if not exist "xcolor.exe" ("%jsc%" /nologo /out:"xcolor.exe" "%~0")
  rem programm aufrufen um Hilfe anzuzeigen
xcolor
echo:
  rem Demo:
xcolor -f 12 -b 1 -s "Hallo Welt" 
xcolor -f 15 -b 12 -s "Hallo Welt" -n
xcolor -f 4 -b 14 -s "Hallo Welt" -n
endlocal
pause
exit /b 
rem in der nächsten Zeile beginnt der Code für xcolor.exe */


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;


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;
0
Erzesel  12.12.2019, 08:08
@Blackbanana33

Hier noch der Findstring-Trick

@echo off
  rem erzeuge ein BackSpace  (gehört  zu xColor)
for /F "delims=;" %%a in ('"prompt $H; & for %%. in (nix) do call "') do (set "BS=%%a")


  rem  ab  hier  kannst  Du  in die Batch  screiben  was  Du  möchtest...
  
rem call :xColor VordergrundHindergrund "text zu schreiben" [Zahl der Zeilenvorschübe]
rem Einschränkung: Sonderzeichen / \ : * ? " < > |  sind nicht zulässig oder es geht nur  mit weiterer Zauberei  
call :xColor fc "Willkommen" 
call :xColor ce " Fremder" 1
call :xColor 0C "Nach 4 Leerzeilen..." 5
call :xColor 5f "...geht  " 0
call :xColor 9b " es " 
call :xColor 20 "weiter" 11
call:xcolor  cf ""
)

  rem Batch ende
pause 
exit /b


  rem Subroutinen


  rem parameters %1= colorcode  %2="text   "  [%3=Anzahl der Zeilenvorschübe]
  rem ohne parameter 3 schreibt der  nächste befehl in der gleichen Zeile  weiter


  rem so funktioniert der Code...
  rem findstring gibt mit parameter /a color im resultat einen farbigen Dateinamen:gefundene Zeichenkette aus 
  rem also schreiben wir ein Backspace in eine Datei deren Name unseren Text enthält.
  rem Findstring zeigt den farbigen Dateinamen und Backspace löscht den Doppelpunkt
:xColor
  rem   New catch error if  %2 is an Empty Variable
if [%2]==[""] (goto :___lf )
pushd %cd%
cd /d %temp%  
<nul set /p=%BS%>"%~2"
findstr /v /a:%1 /R "$" "%~2" nul 2>nul
del "%~2" > nul 2>&1
popd
:___lf
rem erzeuge Zeilenvorschübe
if not .%3==. (for /l %%n in (1,1,%3) do echo.)


exit /b
0
Erzesel  12.12.2019, 08:14
@Blackbanana33

und das ganze mit Powershell:

@echo off 
rem erzeuge ein BackSpace
for /F "delims=;" %%a in ('"prompt $H; & for %%. in (nix) do call "') do (set "BS=%%a")


call :_color  15 12 "mein Text"
call :_color 9 14 "mein Text2" -nonewline
call :_color 0 11 " %bs%\- /3"
call :hex_color 2f "blub"
pause
exit /b


:hex_color
  rem parameters: %1= Zweistelliger Colorcode wie  bei Color   %2= "text"  [%3=-nonewline] ...unterdrückt  Zeilenvorschub
set "x=%1"
set /a "x1=0x%x:~0,1%"
set /a "x2=0x%x:~1,1%"
powershell -Command write-host '%2' %3 -foregroundcolor %x1% -backgroundcolor %x2%
exit /b
:_color
powershell -Command write-host '%3' %4 -foregroundcolor %1 -backgroundcolor %2
exit /b
0
Erzesel  12.12.2019, 08:18
@Blackbanana33

Hier noch eine Kleine Spielerei mit der Findstr-Methode

(schrecklich langsam)

@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 "        _`\    ;"&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(
pause
subst
dir ':\*.*
pause
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
0

ANSI-Sequenzen. Ich weiß nicht, ob das unter Win 10 noch funktioniert.

Wir haben sowas während der DOS-Ära benutzt. Unter Linux geht es heute noch in entsprechend gecodeten Shell-Scripts.

Sieh hier mal rein: https://im-coder.com/liste-der-ansi-color-escape-sequenzen.html

Blackbanana33 
Fragesteller
 10.12.2019, 22:41

Bei Folgenden Wörtern habe ich keine Ahnung was sie bedeuten

ANSI-Sequenzen

Dos-Ära

Linux

Shell-Scripts

und noch eine Frage Kann ich das was beim Link verstehen wenn ich von den Wörtern keine Ahnung habe?

0