Войти

Показать полную графическую версию : [решено] Как пользоваться ключем /A команды Findstr


Dragokas
26-03-2013, 02:51
Можете, пожалуйста, привести практический пример пользы от этого ключа.

Iska
26-03-2013, 06:22
Не встречался.

Foreigner
26-03-2013, 07:29
@echo off

1>"%temp%\1.txt" (

echo test
echo second
echo third test string

)

:: выведет название файла
findstr /a:0c "test" "%temp%\*"

:: выведет номера строк в файле
findstr /n /a:0e "test" "%temp%\1.txt"

:: выведет название файла и номера строк
findstr /n /a:0d "test" "%temp%\*"

Iska
26-03-2013, 11:30
А в чём польза?

Dragokas
27-03-2013, 01:53
Foreigner, спасибо. То, что нужно.

Iska, визуализация (имена файлов/номера строк выделяются другим цветом)

Баг:
echo >s
findstr /V /a:0d "1" "*"

Разрабы забыли в коде команды поставить точку возле эха :))

Польза в том, что я хотел на основе этого сделать разноцветный вывод в консоль.
Но у MS другие понятия о красоте.
Добавил ключ /M, а оно взяло и обесцветило имя файла :(
Да и все печатается с переносом каретки, BackSpace не применить.

Ничего более умного не придумал:
@echo off
SetLocal
mode con: cols=60 lines=10
Color 9A

Set Text=Maded by Dragokas
Set Color=1A
::left, right, center
Set Alignment=right

Call :ColorText "%text%" "%color%" "%Alignment%"
Call :ColorText "Working with Colors" "1d" "center"
Echo Press any key...
pause>nul
goto :eof

:ColorText %1-in.Text %2-in.Color.HEX %3-Alignment
Call :SetTextPosition "%~1" "%~3"
md "%temp%\_bin2" 2>nul
pushd "%temp%\_bin2"
echo.>"%~1"
findstr /V /a:%~2 "1" "*"
popd
rd /s /q "%temp%\_bin2"
Exit /B

:SetTextPosition %1-in.Text %2-in.Alignment
if /i "%~2" neq "left" (
call :GetConsoleWidth _ConWidth
call :var_count "%~1" _len
SetLocal EnableDelayedExpansion
if /i "%~2"=="right" (
Set /A _ind=!_ConWidth!-!_len!-1
Call :indent !_ind!
)
if /i "%~2"=="center" (
Set /A _ind=^(!_ConWidth!-!_len!^)/2
Call :indent !_ind!
)
EndLocal
)
Exit /B

:GetConsoleWidth %1-out.ConsoleWidth
For /F "skip=4 tokens=2" %%w In ('mode con') Do Set %~1=%%w& Exit /B

:var_count %1-in.Text %2.out.Len.of.Text
set _var=%~1& set _count=0
:count--
set _var=%_var:~1%
set /a _count+=1
if not defined _var (set %~2=%_count%& exit /b) else (goto :count--)

:indent %1-in.Count.of.Spaces
SetLocal EnableDelayedExpansion
::Здесь нужно заменить символ ниже на BackSpace (код 0x08) <<<<<---------
Set _BS=
Set _Spaces=
for /L %%C in (1,1,%~1) do Set "_Spaces=!_Spaces! "
<nul set /p "_Spaces=_%_BS%%_Spaces%"
EndLocal& Exit /B

4-я строка снизу Set _BS= здесь поставить символ BackSpace (0x08)

Ограничения кода:
1) В конце строки всегда печатается символ "двоеточие".
2) Нельзя печатать текст из символов, которые не могут быть использованы в имени файла |\:"<>?/*, а также . (точка) и другие служебные CMD.
3) Строка всегда заканчивается переносом каретки.
4) В сценарии используется символ BackSpace (для функции отступа), который нельзя создать обычным блокнотом ^_^

amel27
13-08-2013, 14:50
1) В конце строки всегда печатается символ "двоеточие".
2) Нельзя печатать текст из символов, которые не могут быть использованы в имени файла |\:"<>?/*, а также . (точка) и другие служебные CMD.
3) Строка всегда заканчивается переносом каретки.
4) В сценарии используется символ BackSpace (для функции отступа), который нельзя создать обычным блокнотом ^_^ »
п.1 можно решить помещением BackSpace в файл
п.4 уже решен (http://www.dostips.com/forum/viewtopic.php?f=3&t=1855&p=7565):
@echo off
setlocal EnableDelayedExpansion
call :BL.String.CreateBS_ESC
for /L %%n in (1,1,10000) DO (
<nul set /p "=!BS!!BS!!BS!!BS!!BS!%%n"
)
goto :Eof


:BL.String.CreateBS_ESC
:: Creates two variables with one character BS=Ascii-08 and ESC=Ascii-27
:: BS and ESC can be used with and without DelayedExpansion
:: @attention $H produce a <BS><space><BS>, so we need # and <space> as delims
setlocal
for /F "tokens=1,3 delims=# " %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
ENDLOCAL
set "BS=%%a"
set "ESC=%%b"
goto :EOF
)
goto :eof

Dragokas
13-08-2013, 22:31
п.4 уже решен: »
Well Gracias :) Почитаю.

п.1 можно решить помещением BackSpace в файл »
Спасибо, так и сделали. А потом обернули все это в функцию печати разным цветом в одной строке.
Частично не дописал демо-режим (хотел цветовую палитру - видимо, когда дописал функционал - заснул :lazy2: ).
Рабочий прототип с оптимизацией под скорость:

@echo off
:: Цветной вывод в консоли
:: Автора: Dragokas and FraidZZ
:: Часть кода (получение служебного символа BackSpace 0x08) заимствована у jeb (dostips.com)

:: Демонстрация работы с функцией окрашивания текста в консоли

:: Эти 6 строк оставляем как есть (это часть функции цвета - Инициализация)
SetLocal
md "%temp%\_ColorText" 2>nul
pushd "%temp%\_ColorText"
if %errorlevel%==0 del /F /A /Q *.*
set LastColorText=Default
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%A in (1) do rem"') do set "DEL=%%a"& <nul set /p "x=%%a">Default

:: Настраиваю консоль по вкусу: по-шире - параметр cols. Высоту по-уже - параметр lines.
mode con cols=100 lines=40
Color 17
echo Выше по коду командой Color настраиваем цвет вывода консольных команд по-умолчанию.
echo Справка: Color /?
echo 17 - это белый шрифт на синем фоне.
echo.

:: Концевой пробел и спецсимволы запрещены
Call :ColorText 0B "Мой текст ярко-голубым цветом на черном фоне))"
Call :ColorText 0D " Печатаю в этой же строке розовым цветом"
Call :ColorText 0A ". Зеленым"
echo.

:: Однострочная многоцветная команда
Call :ColorText 0C "Каждый" 06 " охотник" 0E " желает" 0A " знать" 0B " где" 09 " сидит" 03 " фазан"

:: echo. - это переход на новую строку.
echo.&echo.
Call :ColorText 4B "Демонстрация завершена"
echo.&echo.
Call :ColorText 0E "Вывожу справку"
echo.&echo.

:: Это Вам не нужно и все, что ниже для работы функции тоже не нужно (кроме самой функции :ColorText, естественно :)
for /f "delims=] tokens=1*" %%a in ('color /?^| find /n /v ""^| findstr /R "\[[123456789]\]"') do echo.%%b
echo.


::Эти последние строки - служебные (не трогать!!!)
popd
::rd /s /q "%temp%\_ColorText" 2>nul
pause>nul
goto :eof


:ColorText
:: Функция печати цветного текста
:: %1-вх.параметр - Цвет в формате HEX
:: %2-вх.параметр - Текст в цвете
:: Концевой пробел, одиночная концевая точка, знаки \?:*"<>| не могут быть использованы в качестве текста
ren "%LastColorText%" "%~2" 2>nul
set "LastColorText=%~2"
findstr /V /a:%~1 "Like color text? Just ask Dragokas and FraidZZ how it possible :)" "%~2*" 2>nul
if "%~3"=="" Exit /B
shift& shift& goto ColorText

Anonymоus
07-09-2013, 01:23
Решил немного расцветить вывод своего скрипта, отметив ошибки, предупреждения и сообщения от различных потоков цветом. Поиск выдал эту тему. Но решение товарища Diskretor (он же - Dragokas, ежели не ошибаюсь?) имеет ряд недостатков, которые заставили меня поискать другой выход. Это и использование временного файла, и запрет на концевые пробелы и спецсимволы. Поэтому после продолжительного сидения над блокнотом, написал вот такую штуку:

@Echo Off
SetLocal EnableDelayedExpansion
:: Inquisitor, 2013
:: Использованы следующие материалы:
:: Быстрое получение длины строки: CyberMuesli, http://forum.oszone.net/showpost.php?p=2164186
:: Получение 0x08: jeb, http://www.dostips.com/forum/viewtopic.php?p=6827#p6827
:: Идея передачи нескольких параметров: Diskretor, http://forum.oszone.net/post-2201046-7.html


Echo.
Call :EchoColor 00 " "
Call :EchoColor 0D "My Little Cmd" /n
Call :EchoColor 00 " "
Call :EchoColor D0 "Coding is Magic" /n
Echo.
Echo Simple demo:
Call :EchoColor 0A " Text 0123 \>|</&^:;.,*-+=" /n
Call :EchoColor 08 " -[" 6C " R " 2E " a " 1A " i " 5B " n " 79 " b " 3D " o " F4 " w " 08 "]-" /n
Pause&Exit



:EchoColor [%1=Color %2="Text" %3=/n (CRLF, optional)] (Support multiple arguments at once)
:: Вывод цветного текста. Ограничения - не выводится восклицательный знак, остальные спецсимволы разрешены.
:: Работа с более, чем одним набором параметров
If Not Defined multiple If Not "%~4"=="" (
Call :EchoWrapper %*
Set multiple=
Exit /B
)
SetLocal EnableDelayedExpansion
If Not Defined BkSpace Call :EchoColorInit
:: Экранирование входящего текста от обратных и прямых слэшей, чистка некоторых символов.
Set "$Text=%~2"
Set "$Text=.%BkSpace%!$Text:\=.%BkSpace%\..\%BkSpace%%BkSpace%%BkSpace%!"
Set "$Text=!$Text:/=.%BkSpace%/..\%BkSpace%%BkSpace%%BkSpace%!"
Set "$Text=!$Text:"=\"!"
Set "$Text=!$Text:^^=^!"
:: Если XP, выводим обычный текст.
If "%isXP%"=="true" (
<nul Set /P "=.!BkSpace!%~2"
GoTo :unsupported
)
:: Подаем текст на stdout, не создавая временных файлов и используя трюк с путём.
:: В случае неудачи (проблемный\слишком длинный путь?) выводим текст as is, без расцветки.
:: Если результирующая длина строки (плюс уже имеющиеся там символы) превышает ширину консоли, то вывод тоже будет неудачным. Но получить текущую позицию каретки программно нельзя.
PushD "%~dp0"
2>nul FindStr /R /P /A:%~1 "^-" "%$Text%\..\%~nx0" nul
If !ErrorLevel! GTR 0 <nul Set /P "=.!BkSpace!%~2"
PopD
:: Убираем путь, имя файла и дефис с помощью рассчитаного ранее количества символов.
For /L %%A In (1,1,!BkSpaces!) Do <nul Set /P "=!BkSpace!"
:unsupported
:: Выводим CRLF, если указан третий аргумент.
If /I "%~3"=="/n" Echo.
EndLocal
GoTo :EOF

:EchoWrapper
:: Обработка аргументов поочерёдно
SetLocal EnableDelayedExpansion
:NextArg
Set multiple=true
:: Ох уж это удвоение "^" при передаче аргументов...
Set $Text=
Set $Text=%2
Set "$Text=!$Text:^^^^=^!"
If Not "%~3"=="" If /I Not "%~3"=="/n" (
Shift&Shift
Call :EchoColor %1 !$Text!
GoTo :NextArg
) Else (
Shift&Shift&Shift
Call :EchoColor %1 !$Text! %3
GoTo :NextArg
)
If "%~3"=="" Call :EchoColor %1 !$Text!
EndLocal
GoTo :EOF


:EchoColorInit
:: Отрабатывающая при первом запуске родительской функции инициализация нужных переменных
:: Важно! Под XP, в силу реализации тамошнего findstr, 0x08 в путях не работает, заменяясь на точку. Отключаем цветной вывод для XP.
For /F "tokens=2 delims=[]" %%A In ('Ver') Do (For /F "tokens=2,3 delims=. " %%B In ("%%A") Do (If "%%B"=="5" Set isXP=true))
:: Получаем комбинацию "0x08 0x20 0x08" с помощью prompt
For /F "tokens=1 delims=#" %%A In ('"Prompt #$H# & Echo On & For %%B In (1) Do rem"') Do Set "BkSpace=%%A"
:: Рассчитываем требуемое количество символов для подавления всего, кроме выводимого текста
Set ScriptFileName=%~nx0
Call :StrLen ScriptFileName
Set /A "BkSpaces=!strLen!+6"
GoTo :EOF

:StrLen [%1=VarName (not VALUE), ret !strLen!]
:: Получение длины строки
Set StrLen.S=A!%~1!
Set StrLen=0
For /L %%P In (12,-1,0) Do (
Set /A "StrLen|=1<<%%P"
For %%I In (!StrLen!) Do If "!StrLen.S:~%%I,1!"=="" Set /A "StrLen&=~1<<%%P"
)
GoTo :EOF

:: Эта строка должна быть последней и не оканчиваться на CRLF.
-

Спецсимволы разрешены все (кроме "!" и "%"), временные файлы не создаются - использован трюк с путём. Но есть и минусы: если конец выведенной строки близок к границе окна, строка может отобразиться некорректно. Самый важный и большой недостаток - не работает под XP (реализация findstr в XP символы 0x08 в пути отображает точками, соответственно, удалить внутри пути, не c конца строки, ничего нельзя).
Тестировалось на Win 7 (x86\x64), Win Server 2008r2. Под XP цветной вывод просто отключается автоматически.

http://rghost.ru/private/48607718/8dce9e16c347ab9e791dd909674d4763/image.png




© OSzone.net 2001-2012