1 (изменено: Arigato, 2013-01-05 21:43:12)

Тема: CMD/BAT: Вывод разноцветного текста

Предлагаю к рассмотрению две функции, основанные на базе утилиты findstr, которые позволяют выводить текст заданного цвета:

:write
:: Вывести цветную надпись без перевода строки
:: %1 - цвет
:: %2 - текст надписи
:: %3 - флаг, любое значение, если нужно двоеточие в конце строки
:writeLn
:: Вывести цветную надпись с переводом строки
:: %1 - цвет
:: %2 - текст надписи
:: %3 - флаг, любое значение, если нужно двоеточие в конце строки

Пример использования:

call :writeLn 2C "   Hello, World   "

Выведет "Hello, World" красным цветом на зеленом фоне.

Особенности:
1. Цвет задается аналогично команде color, т.е. цвет фона и текста двумя шестнадцатеричными цифрами.
2. Учитывая то, что цветным выводится имя файла, далеко не любой текст можно вывести этим методом. Текст должен быть корректным с точки зрения составления имени файла.
3. В каталоге %TEMP% создается и затем удаляется временный подкаталог.
4. В конце строки можно вывести двоеточие, хотя оно не может присутствовать в имени файла. Для этого надо установить любое значение в качестве третьего параметра функции.
5. Пробелы в конце строки съедаются, в начале строки сохраняются.
6. В строках длинной 78 и 79 символов при выводе в конце может добавиться двоеточие и точка, т.е. если строка подходит к концу экрана.

Пример с двоеточием:

call :write 0F "Random" 1
call :writeLn 0E " %random%"

В таком примере:

call :writeLn 0A "123456789012345678901234567890123456789012345678901234567890123456789012345678"

В конце строки будет выведено двоеточие зеленого цвета и точка обычного цвета.

Полноценный пример и реализация функций в аттаче, т.к. имеются непечатные символы.

http://s019.radikal.ru/i605/1301/11/f1fa003d5d50.png

Post's attachments

color.cmd 1.32 kb, 185 downloads since 2013-01-05 

You don't have the permssions to download the attachments of this post.

2 (изменено: wisgest, 2013-10-23 23:39:16)

Re: CMD/BAT: Вывод разноцветного текста

В целом хорошо, идея ясно выражена — можно в Коллекцию (23.10.2013: сделано) в теперяшнем виде.


Но я попридираюсь:
0) неплохо, если бы в примере присутствовал также вывод с другим цветом фона;
1) если рассматривать работу в полевых условиях, то:
1.1) «~tempFolder» — слишком осмысленное название, велика вероятность попадания;
1.2) могут отсутствовать права на запись в текущую папку; для подобных целей предназначена %TEMP%
1.3)
в экстремальных условиях


(color.cmd>nul) | color.cmd

for /l %i in (1 1 10) do @start "%i" cmd /c color.cmd

(которые не учитываются в большинстве скриптов использующих вспомогательные временные файлы) потерпит неудачу.

3 (изменено: Arigato, 2013-01-05 15:36:39)

Re: CMD/BAT: Вывод разноцветного текста

На счет %TEMP% тоже думал. Изменил первый пост.

4

Re: CMD/BAT: Вывод разноцветного текста

Почему так замысловато

  set dir=%CD%
  %TEMP:~0,2%
  cd %TEMP:~2%
...
  %dir:~0,2%
  cd %dir:~2%

(Почему не PUSHD, POPD или хотя бы CD /D?)

5

Re: CMD/BAT: Вывод разноцветного текста

Переделал и обновил первый пост (аттач).

6 (изменено: wisgest, 2013-01-06 00:13:10)

Re: CMD/BAT: Вывод разноцветного текста

  set tempFolder=~%time:~6,2%%time:~9,2%_%random%.tmp
  md "%tempFolder%"

всё-таки не поможет при одновременном запуске нескольких экземпляров, т.к ни %RANDOM%, ни %TIME% не обеспечивают неповторяемость значений.
Лично я переписал бы это на пару строк длиннее, зато более непробиваемо:

  set x=0
  :write.TRY_MD
  set "tempFolder=%~n0.%x%%time:~-2%"
  md "%tempFolder%" 2>nul
  if errorlevel 1 set /a "x+=1" & goto write.TRY_MD

(последние две строки можно переписать короче:

  md "%tempFolder%" 2>nul || (set /a "x+=1" & goto write.TRY_MD)

)


Для проверки можно попробовать запустить командый файл в нескольких окнах одновременно

for /l %i in (1 1 10) do @start "%i" cmd /c color.cmd

для обоих случаев.

7

Re: CMD/BAT: Вывод разноцветного текста

Также схему

  pushd %TEMP%
  set tempFolder=...
  md "%tempFolder%"
  cd "%tempFolder%"
...
  cd ..
  rd /s /q "%tempFolder%"
  popd

можно сократить на два шага:

  set tempFolder=%TEMP%\...
  md "%tempFolder%"
  pushd "%tempFolder%"
...
  popd
  rd /s /q "%tempFolder%"

В итоге, с учётом сказаного в #6,
процедуру write можно переписать в виде

:write
:: Вывести цветную надпись без перевода строки
:: %1 - цвет
:: %2 - текст надписи
:: %3 - флаг, любое значение, если нужно двоеточие в конце строки
  setlocal
  set x=0
  :write.TRY_MD
  set "tempFolder=%TEMP%\%~n0.%x%%time:~-2%"
  md "%tempFolder%" 2>nul || (set /a "x+=1" & goto write.TRY_MD)
  pushd "%tempFolder%"
  set /p .=.<nul>"%~2"
  findstr /a:%~1 /c:"." /s "%~2"
  if "%~3"=="" (set /p .=  <nul) else set /p .= <nul
  popd
  rd /s /q "%tempFolder%"
endlocal & exit /b

8 (изменено: Arigato, 2013-01-06 14:27:49)

Re: CMD/BAT: Вывод разноцветного текста

Неплохо. Ну а если вместо x использовать random:

:write
:: Вывести цветную надпись без перевода строки
:: %1 - цвет
:: %2 - текст надписи
:: %3 - флаг, любое значение, если нужно двоеточие в конце строки
  setlocal
  :write1
  set "tempFolder=%TEMP%\%~n0.%time:~-2%.%random%"
  md "%tempFolder%" 2>nul || goto write1
  pushd %tempFolder%
  set /p .=.<nul>"%~2"
  findstr /a:%~1 /c:"." /s "%~2"
  if "%~3"=="" (set /p .=  <nul) else set /p .= <nul
  popd
  rd /s /q "%tempFolder%"
endlocal & exit /b

Проблем вроде бы не должно быть.

P.S. На счет меток хотелось бы уточнить. Метка "write.TRY_MD" - 12 символов. Ограничение длинны метки в 8 символов еще действует или это было в старых версиях cmd?

9

Re: CMD/BAT: Вывод разноцветного текста

Arigato пишет:

Ну а если вместо x использовать random:
Проблем вроде бы не должно быть.

Скорее всего, не должно; просто лично у меня предубеждение против повторных обращений при неудаче к датчику псевдослучайных чисел, т.к. чисто теоретически при определённых условиях может произойти его зацикливание.

Arigato пишет:

Ограничение длинны метки в 8 символов еще действует или это было в старых версиях cmd?

В Windows XP такого ограничения нет даже при DISABLEEXTENSIONS, было ли оно в более ранних версиях CMD.EXE — не знаю, но почему-то сомневаюсь. Более вероятно, что это ограничение было в COMMAND.COM.

10 (изменено: Arigato, 2013-01-07 00:52:19)

Re: CMD/BAT: Вывод разноцветного текста

В XP'шной ntcmds.chm написано:

Использование допустимых значений метки
Метка может включать пробелы, но не может включать другие разделители, такие как точка с запятой или знак равенства. В команде goto используются только первые восемь знаков метки. Например, следующие метки эквивалентны и рассматриваются как :hithere0:

:hithere0

:hithere01

:hithere02

Совпадение меток в пакетных программах
Метка, заданная в команде, должна соответствовать метке в тексте пакетной программы. Метка в пакетной программе должна начинаться с двоеточия (:). В Windows XP строка пакетной программы, начинающаяся с двоеточия (:), опознается как метка и не обрабатывается как команда. Если строка начинается с двоеточия, все присутствующие в ней команды обработаны не будут. Если в пакетном файле не содержится заданной метки, программа будет остановлена, а на экран будет выведено следующее сообщение:

Метка не найдена.

11 (изменено: wisgest, 2013-01-07 01:47:14)

Re: CMD/BAT: Вывод разноцветного текста

Я знаю, что написано, но воспроизвести отбрасывание «лишних» знаков, как и метки с пробелами, что-то не получается.

12

Re: CMD/BAT: Вывод разноцветного текста

Идея верна

а так не забывайте ВВС
%system32%\system32\ansi.sys

Я конечно далек от мысли... (с)

13

Re: CMD/BAT: Вывод разноцветного текста

Пардону прошу, а с какими версиями систем совместимо данное изыскание?

14

Re: CMD/BAT: Вывод разноцветного текста

С любыми. Дело не в версии ОС.

15

Re: CMD/BAT: Вывод разноцветного текста

В коллекцию решение так и не попало...

16

Re: CMD/BAT: Вывод разноцветного текста

Всё-таки попало, будут ли замечания?

Задержка связана с тем, что при одновременном запуске большого числа экземпляров всё-таки возникали накладки с созданием временных папок. Теперь, на другом компьютере, это не воспроизводится.
Вот я и гадаю, то ли это связано, с плохим охлаждением того компьютера, из-за чего он при больших нагрузках давал сбои (тогда ничего срашного) или дело в разной файловой системе (FAT и NTFS). Пока перепроверить на старом компьютере руки не доходят (надо чистить, смазывать, возникла необходимость переустанавливать систему).
Единственное место в котором мог возникнуть такой сбой:

  md "%tempFolder%" 2>nul || goto write1

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

17 (изменено: greg zakharov, 2013-10-27 16:50:21)

Re: CMD/BAT: Вывод разноцветного текста

Из логики сценария следует, что всякий раз во временной папке текущего профиля создается временный файл, имя которого равно искомой строке, верно? При этом его содержимое - символ "точка". Здесь то и возникает вопрос для чего делать это постоянно? Допустим есть у нас некоторый файл, например, foo.txt, мы точно знаем что в нем есть символ точки, тогда:

C:\>findstr /p /a:0d /c:"." "colored text\..\E:\foo.txt" nul
colored text\..\E:\foo.txt:some text.

Что имеем в итоге? Цветной текст "colored text\..\E:\foo.txt:" и прочий мусор. То есть, если будет найден способ отбрасывать прочий вывод после "colored text", а также возможные дубликаты строк, то:
1)можно запихать символ точки в конец самого батника и не плодить временные файлы
2)возрастет скорость работы самого батника
3)отпадает надобность в создании кучи функций
В общем, надеюсь, читающим сей пост, суть идеи ясна.

18

Re: CMD/BAT: Вывод разноцветного текста

В общем, в продолжении идеи. Несколько кривоватый батник:

@echo off
  setlocal enabledelayedexpansion
    for /F "tokens=1,2 delims=#" %%i in (^
      '"prompt #$H#$E# & echo on & for %%j in (1) do rem"'^
    ) do (
      set "n=%%i"
    )
    set /p .=.<nul>foo
    call:writeln 0d "colored string"
    del /f /q foo
  endlocal
exit /b

:writeln
  set "regex=%~2" !
  set "regex=!regex:"=\"!"
  findstr /a:%1 /prc:"\." "!regex!\..\foo" nul
  set /p .=%n%%n%%n%%n%%n%%n%%n%%n%%n%<nul
exit /b