Примеры работы со строками в bat/cmd файлах
Присвоить переменной значение пробел
set "charlist= "
-------------------------------------------------------------------------------------------------------
Извлечение подстроки с конца строки
set str=Как утомляет симулировать нормальность
echo.%str%
set str=%str:~-12%
echo.%str%
-------------------------------------------------------------------------------------------------------
Извлечение подстроки с начала строки
set str=Хочешь обнять весь мир - купи глобус
echo.%str%
set str=%str:~0,6%
echo.%str%
-------------------------------------------------------------------------------------------------------
Извлечение подстроки с середины строки
echo.Date : %date%
echo.Weekday: %date:~0,3%
echo.Month : %date:~4,2%
echo.Day : %date:~7,2%
echo.Year : %date:~10,4%
-------------------------------------------------------------------------------------------------------
Удаление первого и последнего символа в строке
(часто этот прием используют для удаления окаймляющих кавычек)
set str=useful
echo %str%
set str=%str:~1,-1%
echo %str%
-------------------------------------------------------------------------------------------------------
Удаление подстроки в строке
В данном примере из строки будет удалена подстрока "кожа "
set str=У тебя кожа 16-летнего персика
echo.%str%
set str=%str:кожа =%
echo.%str%
-------------------------------------------------------------------------------------------------------
Удаление всех пробелов в строке
Как вариант предыдущего примера
set str=Чем больше я сплю, тем меньше от меня вреда.
echo.%str%
set str=%str: =%
echo.%str%
-------------------------------------------------------------------------------------------------------
Замена подстроки в строке
set str=Я тебя раскусил, ты оборотень: то как человек, то как баран
set str=%str:то=иногда%
echo %str%
-------------------------------------------------------------------------------------------------------
Объединение строк
set "str1=Hello"
set "str2=World"
set "str4=%str1%, %str2%"
echo %str4%
Удаление ведущих пробелов
set str= Не ждите чуда, чудите сами
echo."%str%"
for /f "tokens=* delims= " %%a in ("%str%") do set str=%%a
echo."%str%"
-------------------------------------------------------------------------------------------------------
Конвертровать большие буквы в маленькие
:toLower str -- converts uppercase character to lowercase
:: -- str [in,out] - valref of string variable to be converted
:$created 20060101 :$changed 20080219 :$categories StringManipulation
:$source http://www.dostips.com
if not defined %~1 EXIT /b
for %%a in ("A=a" "B=b" "C=c" "D=d" "E=e" "F=f" "G=g" "H=h" "I=i"
"J=j" "K=k" "L=l" "M=m" "N=n" "O=o" "P=p" "Q=q" "R=r"
"S=s" "T=t" "U=u" "V=v" "W=w" "X=x" "Y=y" "Z=z" "А=а"
"Б=б" "В=в" "Г=г" "Д=д" "Е=е" "Ж=ж" "З=з" "И=и" "К=к"
"Л=л" "М=м" "Н=н" "О=о" "П=п" "Р=р" "С=с" "Т=т" "У=у"
"Ф=ф" "Х=х" "Ц=ц" "Ч=ч" "Ш=ш" "Щ=щ" "Ь=ь" "Ы=ы" "Ъ=ъ"
"Э=э" "Ю=ю" "Я=я") do (
call set %~1=%%%~1:%%~a%%
)
EXIT /b
Глядя на этот пример не составит трудности написать процедуру обратного преобразования.
-------------------------------------------------------------------------------------------------------
ЗАМЕНА ОДНОЙ ПОДСТРОКИ НА ДРУГУЮ В ФАЙЛЕ
Для выполнения этой операции можно использовать утилиту sbs2.comТрадиция и дошедший комментарий приписывает авторство Herbert Kleebauer. Получить эту программку можно выполнив следующий бат файл:
rem Create the assembler program, by Herbert Kleebauer
echo Bj@jzh`0X-`/PPPPPPa(DE(DM(DO(Dh(Ls(Lu(LX(LeZRR]EEEUYRX2Dx=>sbs2.com
echo 0DxFP,0Xx.t0P,=XtGsB4o@$?PIyU!WvX0GwUY Wv;ovBX2Gv0ExGIuht6>>sbs2.com
echo ?@}IKuNWpe~Fpe?FNHlF?wGMECIQqo{Ox{T?kPv@jeoSeIlRFD@{AyEKj@>>sbs2.com
echo iqe~1NeAyR?mHAG~BGRgB{~H?o~TsdgCYqe?HR~upkpBG?~slJBCyA?@xA>>sbs2.com
echo LZp{xq`Cs?H[C_vHDyB?Hos@QslFA@wQ~~x}viH}`LYNBGyA?@xAB?sUq`>>sbs2.com
echo LRy@PwtCYQEuFK@A~BxPtDss@fFqjVmzD@qBEOEenU?`eHHeBCMs?FExep>>sbs2.com
echo LHsPBGyA?@xAunjzA}EKNs@CA?wQpQpKLBHv?s`WJ`LRCYyIWMJaejCksl>>sbs2.com
echo H[GyFGhHBwHZjjHeoFasuFUJeHeB?OsQH[xeHCPvqFj@oq@eNc?~}Nu??O>>sbs2.com
echo ~oEwoAjBKs?Zp`LBzHQzyEFrAWAG{EFrAqAGYwHTECIQ{coKIsaCsf{Oe~>>sbs2.com
echo CK}Ayre~CNFA{rAyEKFACrA{EKGAjbA}eKGSjNMtQFtc{OAyDGFj?{FDGQ>>sbs2.com
echo KAjNVk_OCAx@e?f{o?CosI}1EGizhljJ~H1ZeG}JBA~rACBMDGjjDG@g0>>sbs2.com
echo Bj@jzh`0X-`/PPPPPPa(DE(DM(DO(Dh(Ls(Lu(LX(LeZRR]EEEUYRX2Dx=>sbs2.com
echo 0DxFP,0Xx.t0P,=XtGsB4o@$?PIyU!WvX0GwUY Wv;ovBX2Gv0ExGIuht6>>sbs2.com
echo ?@}IKuNWpe~Fpe?FNHlF?wGMECIQqo{Ox{T?kPv@jeoSeIlRFD@{AyEKj@>>sbs2.com
echo iqe~1NeAyR?mHAG~BGRgB{~H?o~TsdgCYqe?HR~upkpBG?~slJBCyA?@xA>>sbs2.com
echo LZp{xq`Cs?H[C_vHDyB?Hos@QslFA@wQ~~x}viH}`LYNBGyA?@xAB?sUq`>>sbs2.com
echo LRy@PwtCYQEuFK@A~BxPtDss@fFqjVmzD@qBEOEenU?`eHHeBCMs?FExep>>sbs2.com
echo LHsPBGyA?@xAunjzA}EKNs@CA?wQpQpKLBHv?s`WJ`LRCYyIWMJaejCksl>>sbs2.com
echo H[GyFGhHBwHZjjHeoFasuFUJeHeB?OsQH[xeHCPvqFj@oq@eNc?~}Nu??O>>sbs2.com
echo ~oEwoAjBKs?Zp`LBzHQzyEFrAWAG{EFrAqAGYwHTECIQ{coKIsaCsf{Oe~>>sbs2.com
echo CK}Ayre~CNFA{rAyEKFACrA{EKGAjbA}eKGSjNMtQFtc{OAyDGFj?{FDGQ>>sbs2.com
echo KAjNVk_OCAx@e?f{o?CosI}1EGizhljJ~H1ZeG}JBA~rACBMDGjjDG@g0>>sbs2.com
В результате, в папке, где будет запущен приведенный выше текст, создастся файл sbs2.com.
Возможно, вы будете приятно удивлены его размером - 659 БАЙТ!
Те, кому вышеприведенные изыски кажутся излишними, могут скачать готовую утилиту здесь.
Использование:
sbs2.com 0 "Old String" "New String" < infile > outfile
Осуществляется замена всех вхождений Old String на New String в файле infile. Результат запишется в файл outfile.
Такую задачу можно решить без использования сторонних программ, только средствами bat !
Ниже приведен пример с использованием локальной процедуры txtrepl
setlocal ENABLEDELAYEDEXPANSION
echo off
call :txtrepl end finish C:\1\24i.bat C:\1\24i.ba1
pause
exit
:txtrepl
rem param - find, repl, from, to
set FINDTXT=%1
set REPLTXT=%2
if EXIST %3 (
set FILEFROM=%3
) else (
echo error. Not found file %3
pause
exit
)
set FILEOUT=%4
set COUNT=0
for /F "tokens=*" %%n in (!FILEFROM!) do (
set /A COUNT=!COUNT!+1
set LINE=%%n
set TMPR=!LINE:%FINDTXT%=%REPLTXT%!
if !COUNT! == 1 (
Echo !TMPR!>!FILEOUT!
) else (
Echo !TMPR!>>!FILEOUT!
)
)
exit /b
rem end of proc
-------------------------------------------------------------------------------------------------------
Вывод на экран, в файл текста без перевода строки
В bat/cmd командах не предусмотрена возможность вывода данных без перевода строки. Но для решения такой задачи можно использовать некую уловку.Команда set с параметром, предусматривающим ввод данных с экрана, позволяет вывести подсказку для ввода без перевода строки. Вот этим мы и воспользуемся.
<nul set /p a=text В данном случае, слово text (а здесь может быть и переменная) будет выведено но экран без перевода строки. Значение переменной a при этом не будет изменено (если это для вас важно).
Соответственно, для вывода текста в файл без перевода строки используется конструкция:
<nul set /p a=text>b.txt
Использование этого приема в сочетании с символом backspace (код 08) позволяет сделать вывод на экран изменяемого текста и как вариант - "вращающейся палки".
-------------------------------------------------------------------------------------------------------
Вычисление длины строковой переменной
В bat/cmd командах нет функции, позволяющей вычислять длину строковой переменной. А такая задача возникает не так уж и редко. Однако средств командного языка достаточно, для того что бы решить такую задачу, не прибегая к использованию специальных программ. Рассмотрим несколько вариантов решения данной задачи:
:var_count2
set /a %2 =0
set var=%~1
:startvarcount
if not defined var exit /b
set var=%var:~1%
set /a %2+=1
goto startvarcount
exit /b
Пример вызова
set st=abcdefghijklmnopqrstuvwxyz
...
call :var_сount2 %st% count2
echo %count2%
Еще один вариант вычисления длины строковой переменной:
:StringLen
:: -----------------------
:: Нахождение длины строки
:: -----------------------
:: %1 - текстовая строка
:: -----------------------
Set $StringLen=0
Set $StringBuf=%~1
If ""=="%~1" GoTo :EOF
:StringLenLoop
Set /A $StringLen+=1
Call Set $StringChr=%%$StringBuf:~%$StringLen%%%
If ""=="%$StringChr%" GOTO :EOF
GoTo :StringLenLoop
Пример вызова
Call :StringLen "Очень важная срока"
Echo %$StringLen%
Еще один способ определения длины строки, как ни странно - достаточно быстрый:
@Echo Off
Set a=qwertyuiop
Echo.%a%>"%TEMP%\%~n0.tmp"
For %%i In ("%TEMP%\%~n0.tmp") Do Set /A z=%%~zi-2
Echo %z%
Ну и, наконец, решение, поразившее меня своей математической лаконичностью:
:strLen string len -- returns the length of a string
:: -- string [in] - variable name containing
:: the string being measured for length
:: -- len [out] - variable to be used
:: to return the string length
:: Many thanks to 'sowgtsoi', but also 'jeb'
:: and 'amel27' dostips forum
:: users helped making this short and efficient
:$created 20081122
:$changed 20101116
:$categories StringOperation
:$source http://www.dostips.com
( SETLOCAL ENABLEDELAYEDEXPANSION
set "str=A!%~1!"&rem keep the A up front to ensure we
rem get the length and not the upper bound
rem it also avoids trouble in case of empty string
set "len=0"
for /L %%A in (12,-1,0) do (
set /a "len|=1%<<%%A"
for %%B in (!len!) do ^
if "!str:~%%B,1!"=="" set /a "len&=~1<<%%A"
)
)
( ENDLOCAL & REM RETURN VALUES
IF "%~2" NEQ "" SET /a %~2=%len%
)
EXIT /b
Пример вызова
set "string=12345678901234 "
call :strLen string len
echo len=%len%
Для себя я так же использую метод половинного деления для нахождения количества символов в строке. Эта процедура менее изящна, и, возможно, потребует несколько большего времени для вычислений, чем приведенная выше, но, на мой взгляд, она понятнее. (В этом месте надо было похвалить себя еще, но что-то не нашлось достойных эпитетов)
Привожу на всякий случай и эту процедуру ))
@echo off
setlocal ENABLEEXTENSIONS
SetLocal EnableDelayedExpansion
set "string=123456789012345678901"
call :strLen string len
echo len=%len%
pause
exit
:strLen string len
:: - string [in] - variable name containing the string
:: -- len [out] - variable to be used to return the string length
SETLOCAL ENABLEDELAYEDEXPANSION
set /a nn=10 & rem max length string = 2^^nn.
rem If nn=10 - max length=1024
set /a mmin=0
set /a mmax=1"<<"%nn%
set "str=Q!%1!"
for /L %%A in (%nn%,-1,1) do (
set /a BB = ^(!mmin! + !mmax!^) ">>" 1
call set sim=%%str:~!BB!,1%%
if "!sim!" == "" ( set /a mmax=!BB!) else ( set /a mmin=!BB! )
)
ENDLOCAL & SET /a %~2=%mmin%
EXIT /b %mmin%
-------------------------------------------------------------------------------------------------------
Получение подстроки.
Если смещение начала подстроки и ее длина являются константами - здесь все достаточно просто и аналогичный пример рассматривался выше:
set str=123qwerty456
set d=%str:~3,6%
echo %d%
Прошу прощения, если в качестве значения переменной str я опубликовал чей-то пароль )).
Если же одна или обе эти величины - переменные, то решение будет не столь простое.
Здесь встретиться возможно не совсем обычное применение команды CALL. Немного глубже об этом на странице Полезное в разделе Особенности использования команды CALL. Там же рассмотрен и этот пример.
Итак, рассмотрим возможные решения:
set str=123qwerty456
set n1=3
set n2=6
Call Set d=%%str:~%n1%,%n2%%%
Echo d=%d%
Очередное решение:
SetLocal EnableDelayedExpansion
set str=123qwerty456
set n1=3
set n2=6
Set d2=!str:~%n1%,%n2%!
Echo d2=%d2%
Или как вариант предыдущего
setlocal ENABLEEXTENSIONS
SetLocal EnableDelayedExpansion
set str=zaq12wsx
set n1=3
set n2=6
call :SUBSTRING str,%n1%,%n2%
echo %SUBD%
........
:SUBSTRING
set SUBD=!%1:~%2,%3!
exit /b
-------------------------------------------------------------------------------------------------------
Удаление ведущих и замыкающих пробелов.
:ALLTRIM
:: -----------------------
:: Krasner B.
:: -----------------------
:: %1 - var with txt string
:: -----------------------
SetLocal EnableDelayedExpansion
set /a firstnoblank=-1
set /a lastnoblank=0
set /a curpos=1
set "str=Q!%1!"
:StringLenLoop
set SUBD=!str:~%curpos%,1!
if "!SUBD!" == "" GoTo :formrez
if NOT "!SUBD!" == " " (
if !firstnoblank! == -1 set firstnoblank=!curpos!
set lastnoblank=!curpos!
)
set /a curpos = !curpos!+1
GoTo :StringLenLoop
:formrez
set /a n1=!firstnoblank!-1
set /a n2=!lastnoblank!-!firstnoblank!+1
if !firstnoblank! == -1 (set "rez=") else (set rez=!%1:~%n1%,%n2%!)
ENDLOCAL & SET %~1=%rez%
exit /b 0
)
Пример вызова:
set "strr="
Call :ALLTRIM strr
echo result ALLTRIM ^>%strr%^<
:::::::::::::
set "strrr= 22 33 "
Call :ALLTRIM strrr
echo result ALLTRIM ^>%strrr%^<
Для вопросов, обсуждений, замечаний, предложений и т. п. можете использовать раздел форума этого сайта (требуется регистрация).