Wie kann man in einer Batchdatei Text in zwei Farben anzeigen lassen?
Ganz einfach gesagt
In die erste Zeile soll der Text Grün sein und in der Zweiten Blau.
Wichtig beide Zeilen soll man Gleichzeitig sehen.
2 Antworten
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...
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;
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
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
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
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
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?
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.