Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - Расширение возможностей Echo

Ответить
Настройки темы
CMD/BAT - Расширение возможностей Echo

Старожил


Сообщения: 415
Благодарности: 257

Профиль | Отправить PM | Цитировать


Доброго времени суток, уважаемые.
Недавно понадобился мне в одном из скриптов вывод текстовой строки поверх предыдущей, после поисков в интернете было найдено несколько консольных утилит, позволяющих такое сделать. Но пораскинув немного мозгами, я решил обойтись без сторонних утилит, стандартными средствами командного процессора. Вот, решил выложить тут, авось кому еще пригодится. Критика тоже приветствуется.
Реализация подсмотрена здесь .
Возможности - вывод текста без переноса на другую строку, форматирование длинных строк, удаление строк, установка курсора в нужную позицию на строке, заполнение строкой нужной длинны, состоящей из пробелов, вывод текста поверх другого текста, имитация посимвольного плавного ввода текста ("печатная машинка"). Все (или почти все) показано в коротеньком демо, запускающемся при старте скрипта. Также наличествует встроенная справка по "командам".

Собственно, сам скрипт (кодировка 866):
Код: Выделить весь код
@Echo Off
Rem Демо, показывающее основные возможности
Rem =======================================================
Title  libType - Demo
Call :libType echo "Пример вывода обычной текстовой строки."
Call :libType qwrite "Предыдущая строка была напечатана с использованием эффекта 'печатной машинки', а эта - нет."
Call :libType break
Call :libType write "А эта строка сейчас будет удалена. Нажмите любую кнопку..."
Pause>nul
Call :libType erase
Call :libType write "Также, можно выводить текст поверх другой строки:"
Call :Delay
Call :libType return 40
Call :libType echo "   НАПРИМЕР, ВОТ ТАК   "
Call :libType echo "Или выводить на экран недавно напечатанную строку"
Call :Delay
Call :libType echo
Call :libType echo
Call :libType write "Ну и конечно же, дописывать к строке"
Call :Delay
Call :libType echo ", как это происходит сейчас."
Call :libType break
Call :libType break
Call :libType autowidth "  Длинные строки можно выводить двумя способами - в первом на строки текст разбивает командный процессор, во втором случае, этим занимается скрипт, удобно разбивая текст на подстроки, помещающиеся по ширине в границы консоли, при желании можно задать отступы, как это видно в этом примере."
Call :libType break
Call :libType break
Call :libType write "Пример длинной строки 1: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin vel dolor non turpis varius tempus. Vestibulum quis posuere mauris. Vivamus ac libero at enim dapibus bibendum. Suspendisse feugiat ante sit amet dui tristique dignissim."
Call :libType break
Call :libType break
Call :libType autowidth "  Пример длинной строки 2: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin vel dolor non turpis varius tempus. Vestibulum quis posuere mauris. Vivamus ac libero at enim dapibus bibendum. Suspendisse feugiat ante sit amet dui tristique dignissim."
Call :libType break
Call :libType break
Call :libType qwrite "     Нажмите любую кнопку для перехода к справке..."
Pause>nul
Call :libType help
Exit
:Delay
ping -n 2 127.0.0.1>nul&Exit /B
Rem =======================================================

Rem Передача параметров функции при вызове из другого батника
Call :libType %*
Exit /B

:libType
Rem Обёртка, вызывающая нужные функции с передачей аргументов
Call :TCheckArguments %1
If %ErrorLevel% NEQ 0 GoTo THelp
Call :TCheckArguments %2
If %ErrorLevel% NEQ 0 GoTo UseSaved
:SaveLine
If /I "%~1"=="autowidth" Call :TMemorizeLastString %2 & Call :TAutoWidth %2
If /I "%~1"=="write" Call :TMemorizeLastString %2 & Call :TWrite %2
If /I "%~1"=="qwrite" Call :TMemorizeLastString %2 & Call :TQuickWrite %2
If /I "%~1"=="echo" Call :TMemorizeLastString %2 & Call :TEcho %2
If /I "%~1"=="return" Call :TReturn %2
If /I "%~1"=="blank" Call :TBlank %2
Exit /B
:UseSaved
If /I "%~1"=="help" Call :THelp
If /I "%~1"=="--help" Call :THelp
If /I "%~1"=="autowidth" Call :TAutoWidth "%$SavedString%"
If /I "%~1"=="write" Call :TWrite "%$SavedString%"
If /I "%~1"=="qwrite" Call :TQuickWrite "%$SavedString%"
If /I "%~1"=="echo" Call :TEcho "%$SavedString%"
If /I "%~1"=="break" Call :TBreakLine
If /I "%~1"=="return" Call :TReturn
If /I "%~1"=="blank" Call :TBlank
If /I "%~1"=="erase" Call :TEraseString
If /I "%~1"=="clear" Call :TClearLastString
Exit /B

:THelp
Rem Встроенная помошь
Cls
Echo.
Echo                                                     СИНТАКСИС ФУНКЦИИ :libType
Echo.
Echo   (call %~nx0 команда "текст") или (call %~nx0 команда)
Echo   любая введенная строка запоминается до ввода следующей
Echo.
Echo    call %~nx0 help (или --help)
Echo  Показать эту справку
Echo.
Echo    call %~nx0 echo "текст"
Echo  Вывод указанной строки текста с переводом строки в конце, дублирует работу echo.
Echo.
Echo    call %~nx0 echo
Echo  Вывод последней запомненной строки с переводом строки в конце, дублирует работу echo.
Echo.
Echo    call %~nx0 write "текст"
Echo  Вывод указанной строки текста
Echo.
Echo    call %~nx0 write
Echo  Вывод последней запомненной строки текста
Echo.
Echo   call %~nx0 qwrite "текст"
Echo  Быстрый вывод указанной строки текста
Echo.
Echo    call %~nx0 qwrite
Echo  Быстрый вывод последней запомненной строки текста
Echo.
Echo    call %~nx0 autowidth "текст"
Echo  Вывод указанной строки текста с принудительным разбиением по ширине консоли
Echo.
Echo    call %~nx0 autowidth
Echo  Вывод последней запомненной строки текста с принудительным разбиением по ширине консоли
Echo.
Echo    call %~nx0 break
Echo  Вставить перевод строки
Echo.
Echo    call %~nx0 erase
Echo  Стереть текущую строку и вернуть курсор к началу
Echo.
Echo    call %~nx0 return число
Echo  Возвратить курсор на n символов (действует только в пределах строки)
Echo.
Echo    call %~nx0 return
Echo  Возвратить курсор на начало последней запомненной строки текста (действует только в пределах строки)
Echo.
Echo    call %~nx0 blank число
Echo  Заполнить строку длинной n пробелами
Echo.
Echo    call %~nx0 blank
Echo  Заполнить последнюю запомненную строку пробелами
Echo.
Echo    call %~nx0 clear
Echo  Очистить запомненную строку
Echo.
Echo      Нажмите любую кнопку для продолжения...
Pause>nul
Echo.
Echo.
Exit /B      

:TWrite
Rem Посимвольный вывод с имитацией эффекта печатной машинки.
Rem В отличии от Echo, не переводит на новую строку в конце текста.
If Not Defined $Text Set $Text=%~1
If Not Defined $Text Exit /B
<nul Set /P $Text=%$Text:~0,1%
Ping -n 1 127.0.0.1>nul 
Set $Text=%$Text:~1%
If Defined $Text (GoTo :TWrite) Else (Exit /B)

:TQuickWrite
Rem То же самое, что и TWrite, но без задержки
If Not Defined $Text Set $Text=%~1
If Not Defined $Text Exit /B
<nul Set /P $Text=%$Text:~0,1%
Set $Text=%$Text:~1%
If Defined $Text (GoTo :TQuickWrite) Else (Exit /B)

:TReturn
Rem Возврат курсора на заданное число символов в пределах строки
Rem Используется символ "" (0x08)
Call :TGetLenght "%$SavedString%"
Set genChars=%strLenght%
If Not "%1"=="" (Set genChars=%1)
If "%genChars%"=="" (Exit /B)
Set tmpString=
:genReturn
Set tmpString=%tmpString%
Set /A genChars-=1
If %genChars% LEQ 0 (
Call :TQuickWrite "%tmpString%"
Exit /B
) Else (
GoTo genReturn
)

:TBlank
Rem Вывод строки заданной длинны, заполненной пробелами
Rem Используется символ " " (0x20)
Call :TGetLenght "%$SavedString%"
Set genChars=%strLenght%
If Not "%1"=="" (Set genChars=%1)
If "%genChars%"=="" (Exit /B)
Set tmpString=
:genBlank
Set tmpString=%tmpString% 
Set /A genChars-=1
If %genChars% LEQ 0 (
Call :TQuickWrite "%tmpString%"
Exit /B
) Else (
GoTo genBlank
)

:TEraseString
Rem Стирание предыдущего выведенного текста
Rem Эффективно только в пределах текущей строки
Call :TReturn
Call :TBlank
Call :TReturn
Exit /B

:TEcho
Rem Алиас для вывода текста и перевода строки. Аналогично Echo.
Call :TWrite %*
Call :TBreakLine
Exit /B

:TGetLenght
Rem Получение длины текстовой строки.
Set /A strLenght=0
Set $String=%~1
:charCounter
If "%$String%"=="" Exit /B
Set /A strLenght+=1
Set $String=%$String:~1%
GoTo charCounter

:TGetConsoleWidth
Rem Получение ширины консоли.
For /F "skip=4 tokens=1,2" %%v In ('mode con') Do (
Set /A conWidth=%%w
Exit /B
)

:TAutoWidth
Rem Форматирование длинных строк под ширину консоли с отступами по 1 символу по бокам.
SetLocal EnableDelayedExpansion
If "!tmpText!"=="" Set tmpText=%~1
Call :TGetConsoleWidth
Set /A conWidth-=2
:printString
Call :TGetLenght "!tmpText!"
If !strLenght! GTR %conWidth% (
Call :TWrite " !tmpText:~0,%conWidth%!"
Echo.
Set tmpText=!tmpText:~%conWidth%!
GoTo printString
) Else (
Call :TWrite " !tmpText!"
Set $tmpText=
)
EndLocal
Exit /B

:TBreakLine
Rem Перевод строки.
Echo.
Exit /B

:TMemorizeLastString
Rem Запоминание выводимой строки.
Set $SavedString=%~1
Exit /B

:TClearLastString
Rem Очистка запомненной строки.
Set $SavedString=
Exit /B

:TCheckArguments
Rem Проверка на наличие аргументов.
Set tmpVar=%~1
If "%tmpVar%"=="" (Exit /B 1) Else (Exit /B 0)
Это сообщение посчитали полезным следующие участники:

Отправлено: 13:33, 06-03-2011

 

Аватара для gora

Ушёл из жизни


Сообщения: 6021
Благодарности: 3491

Профиль | Отправить PM | Цитировать


На Win 7 текст выводится без пробелов (и х86, и х64)

Отправлено: 14:45, 06-03-2011 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

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

njg njg вне форума

Новый участник


Сообщения: 46
Благодарности: 3

Профиль | Отправить PM | Цитировать


Просто шикарно выглядит!

Отправлено: 22:57, 27-07-2011 | #3


Ветеран


Сообщения: 1754
Благодарности: 965

Профиль | Цитировать


Изображения
Тип файла: png 1.png
(65.4 Kb, 79 просмотров)

В cmd не хватает управляющих последовательностей (escape sequences). За чем их выпилили в NT-линейке не понятно. С их помощью все это делается чуть ли не в одну строчку. Хорошо что сторонние разработчики не оставили этого без внимания.
Давно и успешно пользуюсь ansicon

Последний раз редактировалось Foreigner, 28-07-2011 в 00:19.

Это сообщение посчитали полезным следующие участники:

Отправлено: 23:34, 27-07-2011 | #4


Новый участник


Сообщения: 2
Благодарности: 0

Профиль | Сайт | Отправить PM | Цитировать


Спасибо топикстартеру!!! Отличный скрипт.
Однако, начиная с Win7 мелкософты либо накосячили, либо намеренно начали триммировать слева строки при выводе через <nul set /p, в результате терялись пробелы.
Та же петрушка и в Win10

Придумал следующее решение:

Заменить в блоках :TWrite и :TQuickWrite
вывод <nul Set /P $Text=%$Text:~0,1% на условный через проверку:
IF "%$Text:~0,1%"==" " (<nul Set /p s=". ")ELSE (<nul Set /P $Text=%$Text:~0,1%) - т.е. строка начинается с точки, за ней следует BackSpace и только потом пробел.

Пример:
Код: Выделить весь код
:TWrite
Rem Посимвольный вывод с имитацией эффекта печатной машинки.
Rem В отличии от Echo, не переводит на новую строку в конце текста.
If Not Defined $Text Set $Text=%~1
If Not Defined $Text Exit /B
::Начиная с Win7 просходит триммирование строки спереди, т.е. пробелы игнорируются, поэтому приходится изворачиваться
IF "%$Text:~0,1%"==" " (<nul Set /p s=". ")ELSE (<nul Set /P $Text=%$Text:~0,1%)  
Ping -n 1 127.0.0.1>nul 
Set $Text=%$Text:~1%
If Defined $Text (GoTo :TWrite) Else (Exit /B)

:TQuickWrite
Rem То же самое, что и TWrite, но без задержки
If Not Defined $Text Set $Text=%~1
If Not Defined $Text Exit /B
::Начиная с Win7 просходит триммирование строки спереди, т.е. пробелы игнорируются, поэтому приходится изворачиваться
IF "%$Text:~0,1%"==" " (<nul Set /p s=". ")ELSE (<nul Set /P $Text=%$Text:~0,1%)  
Set $Text=%$Text:~1%
If Defined $Text (GoTo :TQuickWrite) Else (Exit /B)

Последний раз редактировалось Vadim.Repin@vk, 21-03-2021 в 15:32.


Отправлено: 15:26, 21-03-2021 | #5


Ветеран


Сообщения: 1274
Благодарности: 564

Профиль | Отправить PM | Цитировать


оно?
Код: Выделить весь код
@echo off
for /f %%a in ('"prompt $H& for %%# in (1) do rem"') do set /p z="%%a                     Если нужны пробелы в начале: "
for /f %%a in ('"prompt $H& for %%# in (1) do rem"') do <nul set /p z="%%a                     Если нужны пробелы в начале"& echo:
pause

Отправлено: 17:19, 21-03-2021 | #6


Новый участник


Сообщения: 2
Благодарности: 0

Профиль | Сайт | Отправить PM | Цитировать


Не знаю. Нет наверное. Команда Echo без проблем выводит пробелы в начале слова без дополнительных усилий.
А вот <nul Set /p s=" R" начиная с Win7 имеет глюк и выводит только голую R. Поэтому код с посимвольным выводом, например для имитации эффекта печатной машинке печатал всё без пробелов.

Вот я и придумал, как заставить напечатать голый пробел в строку при условии, что она этого не хочет делать ))))

Отправлено: 01:16, 22-03-2021 | #7



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - Расширение возможностей Echo

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Прочие - APC PowerChute Alexander_Grig Программное обеспечение Windows 11 25-10-2015 20:14
Sprint Kyocera Echo: смартфон с двумя 3,5-дюймовыми экранами OSZone News Новости информационных технологий 1 08-02-2011 12:10
lenovo y550 + echo indigo iox - зависания tatastha-sakti Ноутбуки 2 31-07-2010 12:21
CMD/BAT - не работает @echo off mitiya Скриптовые языки администрирования Windows 2 10-01-2009 17:37
команда ECHO message cer50nun Программирование и базы данных 1 17-09-2008 14:23




 
Переход