Bat сравнивает строки и операторы Better IF для более эффективной работы с пакетными файлами в Windows

Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.

  • korney61448

Тема: CMD/BAT: Сравнение строк

Задача:
6. Создать командный файл compare.cmd, сравнивающий две строки, передаваемые ему в качестве параметров. Командный файл должен возвращать следующие коды:
        ◦ 0 – строки одинаковы;
        ◦ 1 – строки разные;
        ◦ 2 – не хватает параметров (параметров меньше двух);
        ◦ 3 – «лишние» параметры (параметров больше двух).
Никаких сообщений командный файл выдавать не должен. Вывод на экран отключен.
Создать командный файл для запуска compare.cmd c ретрансляцией параметров. В зависимости от кода завершения, на экран должны выводиться сообщения о результате сравнения.
        7. Модифицировать командный файл, созданный при выполнении предыдущего пункта задания таким образом, чтобы в файл log.txt при каждом сравнении добавлялась следующая информация: дата, время, сравниваемые строки, результат сравнения. В случае неверного числа параметров вместо сравниваемых  строк и результата сравнения должно записываться сообщение об ошибке.

Что сделал я:
file.cmd, запускающий compare.cmd:

date /t>log.txt
time /t>>log.txt
call compare.cmd asd qwe asd
if errorlevel 3 goto :many
if errorlevel 2 goto :little
if errorlevel 1 goto :nesuper
if errorlevel 0 goto :super
:many
echo "Слишком много параметров">>log.txt
exit
:little
echo "Не хватает данных">>log.txt
exit
:nesuper
echo "Строки неравны">>log.txt
exit
:super
echo "Строки равны">>log.txt

и сам compare.cmd:

@echo off
if [not] -%3==- goto :3
if -%1==- goto :2
if -%2==- goto :2
if %1==%2 goto :0
if [not] %1==%2 goto :1
:3 exit /b 3
:2 exit /b 2
:0 exit /b 0
:1 exit /b 1

При запуске file.cmd в log.txt выводится только дата и время. Что я сделал не так?

chichva

  • chichva

Re: CMD/BAT: Сравнение строк

@echo off
if not -%3==- goto :3
if -%1==- goto :2
if -%2==- goto :2
if %1==%2 goto :0
if not %1==%2 goto :1
:3
exit /b 3
:2
exit /b 2
:0
exit /b 0
:1
exit /b 1

Сообщения 2

Переменные. Команда SET

Ввод с клавиатуры

set /p x="BBeduTe cTpoky: "

Ограничение 8184 символа.
Тип число

Ограничение от -2147483647 до 2147483647.

Вывод значения переменных

%RANDOM% – раскрывается в случайное десятичное число между 0 и 32767.(от 0 до (2^17)-1)

set /a random10=%random%/3277

Выводит случайное число от 0 до 9.
У меня это число по нелепой псевдослучайности цифру секунды
%CD% – раскрывается в строку текущей директории.
%DATE% – раскрывается в текущую дату, используя тот же формат команды DATE.
%TIME% – раскрывается в текущую дату, используя формат команды TIME.
%ERRORLEVEL% – раскрывается в текущее значение ERRORLEVEL.
Уровень ошибки, 0 – это нет ошибки, 1 – это есть ошибка, а другие это номера ошибки.

Чтобы получить полный список переменных и их значений введите команду SET

Операции со строковыми или численными переменными

Соединение 2-ух строковых переменных

set x=Gaz
set y=Prom
echo %x%%y%
(GazProm)

Вывод определенного(ых) символа(ов) из строки

Символы номеруются начиная с 0!

Вывод 1-ого символа

Вывод 3-х символов с конца строки

Вывод всей строки кроме 2-ух первых символов

Вывод всей строки кроме 2-ух последних символов

Вывод 3-х символов начиная с 3

Удаление подстроки из строки

set str=babywka
echo %str:ba=%
(bywka)

Замена подстроки из строки на другую подстроку

set str=babywka
echo %str:bab=xlop%
(xlopywka)

Удаление кавычек(“) из строки

set str2="qwerty"
echo %str2:"=%
(qwert)

В данном случае: если кавычки в начале и конце строки – можно юзать

echo %str2:~1,-1%
(qwert)

Существуют 2 способа использовать переменную в переменной, например:

вывод n-ого символа

Первый способ с call set

call set x=%%str:~%n%,1%%
echo %x%

Второй способ с for и setlocal enabledelayedexpansion

setlocal enabledelayedexpansion
for /l %%i in (%n%,1,%n%) do (set x=!str:~%%i,1!)
echo %x%

тут неважно что в for писать, главное

писать в do
С циклами мы разберемся в следующей статье.
Но, пока уточню: если код второго способа юзать в пакетном файле (BATнике), то вместо %i юзаем %%i.

Операции с числовыми переменными

Увеличивание на единицу

Увеличивание в 2 раза

Возведение в квадрат

Возведение в куб

Деление
Деление в CMD является целочисленным!(то есть делится до целого числа)

set /a x=15
set /a y=4
set /a xy=%x%/%y%
(3)
set /a x=5
set /a y=-6
set /a xy=%x%+%y%
(5+(-6)=5-6=-1)
set /a x=5
set /a y=-6
set /a xy=%x%-%y%
(5-(-6)=5+6=11)

Вычисление остатка от деления

(при записи в батник, процент “%” нужно удваивать “%%”)

Логическое отрицание (Logical NOT)

дает результат(%y%) 1 (True), если переменная(%x%) равна 0 (False), и 0 (False) (%y%) в любых других случаях

Например
set /a x=5
set /a y="!"%x%
(0)
set /a x=0
set /a y="!"%x%
(1)

Побитовая инверсия (Bitwise NOT):

дает результат -1-%x% (%y%)
Например

set /a x=5
set /a y="~"%x%
(-1-5=-(1+5)= -6)
set /a x=-3
set /a y="~"%x%
(-1-(-3)=-1+3=3-1= 2)

Унарный минус (устанавливает/сбрасывает знаковый бит)

дает результат 0-%x% (%y%)
Например

set /a x=5
set /a y="-"%x%
(-5)
set /a x=-3
set /a y="-"%x%
(3)
set x=3
(в двоичной системе счисления - 0011)
set y=5
(в двоичной системе счисления - 0101)

Побитовое И (AND)

Побитовое И — это бинарная операция, действие которой эквивалентно применению логического И к каждой паре битов, которые стоят на одинаковых позициях в двоичных представлениях операндов.
Другими словами, если оба соответствующих бита операндов равны 1, результирующий двоичный разряд равен 1; если же хотя бы один бит из пары равен 0, результирующий двоичный разряд равен 0.

set /a xy=%x%"&"%y%
(1, в двоичной системе счисления - 0001)

Побитовое ИЛИ (OR)

Побитовое ИЛИ — это бинарная операция, действие которой эквивалентно применению логического ИЛИ к каждой паре битов, которые стоят на одинаковых позициях в двоичных представлениях операндов.
Другими словами, если оба соответствующих бита операндов равны 0, двоичный разряд результата равен 0; если же хотя бы один бит из пары равен 1, двоичный разряд результата равен 1.

set /a xy=%x%"|"%y%
(7, в двоичной системе счисления - 0111)

Побитовое исключающее ИЛИ (XOR)

Побитовое исключающее ИЛИ (или побитовое сложение по модулю два) — это бинарная операция, действие которой эквивалентно применению логического исключающего ИЛИ к каждой паре битов, которые стоят на

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

set /a xy=%x%"^"%y%
(6, в двоичной системе счисления - 0110)

К битовым операциям также относят битовые сдвиги. При сдвиге значения битов копируются в соседние по направлению сдвига.
Различают сдвиг влево (в направлении от младшего бита к старшему) и вправо (в направлении от старшего бита к младшему).
При логическом сдвиге значение последнего бита по направлению сдвига теряется (копируясь в бит переноса), а первый приобретает нулевое значение.

Двоичный арифметический сдвиг

Арифметический сдвиг аналогичен логическому, но значение слова считается знаковым числом, представленным в дополнительном коде.
Так, при правом сдвиге старший бит сохраняет свое значение. Левый арифметический сдвиг идентичен логическому.

set /a xy=%x%">>"1
(1, в двоичной системе счисления - 0011->0001)
set /a xy2=%y%">>"1
(2, в двоичной системе счисления - 0101->0010)
set /a n=13
(в двоичной системе счисления - 1101)
set /a xn=%n%">>"2
(3, в двоичной системе счисления - 1101->0011)
set /a my=-%y%">>"1
(-3, в двоичной системе счисления - 1011(-5)->1101(-3))
set /a xy=%x%"<<"1
(6, в двоичной системе счисления - 0011->0110)
set /a xy2=%y%"<<"1
(10, в двоичной системе счисления - 0101->1010)
set /a xy3=%y%"<<"4
(80, в двоичной системе счисления - 0101->1010000)
set /a my=-%y%"<<"1
(-10, в двоичной системе счисления - 1011(-5)->10110(-10))

И я забыл, про 8-ричную и 16-ричную систему счисления в CMD

:/>  Как удалить вирус windows powershell

Числовые значения рассматриваются как десятичные, если перед ними не стоит префикс 0x для шестнадцатеричных чисел, и 0 для восьмеричных чисел. Например, числа 0x12, и 022 обозначают десятичное число 18.

Обратите внимание на запись восьмеричных числе: 08 и 09 не являются допустимыми числами, так как в восьмеричной системе исчисления цифры 8 и 9 не используются.

Восьмеричная система счисления

set /a x=022
(Это 22 в восьмеричной системе счисления, и 18 в десятичной)

Можно производить все операции, также как и с десятеричными числами.
Но после задания значения переменной, значение хранится в десятичной системе счисления.
Например, сложение

set /a xy=022+07
(Это 22+7=31 в восьмеричной системе счисления, и 31 в десятичной)

Шестнадцатеричная система счисления

set /a x=0x3A
(Это 3A в восьмеричной системе счисления, и 58 в десятичной)
set /a xy=0x3A-0x66
(Это 3A-66=-54 в восьмеричной системе счисления, и -44 в десятичной)

Сохранение в переменной вывода программы
К сожаление, передача вывода программ на вход команды set не работает:

echo 1|set /p AA=""
set AA

Поэтому можно воспользоваться временным сохранением в файл:

echo 1> 0.tmp
set /p AA="" <0.tmp
del 0.tmp
echo %AA%

Примеры использования
Узнать динамически генерируемое имя архива WinRar:

rar a -z%Comment% -p%p% "-ag yyyy-mm-dd[n]" %OutPath%\%arhivename%.%ext% @%FileList% >rar.log.tmp
for /f "tokens=2*" %%I in ('find /i "Creating archive" ^<rar.log.tmp') do @echo %%J >rarfilename.tmp
set /p rarfilename="" <rarfilename.tmp
del rarfilename.tmp

Узнать имя последнего изменённого файла в папке:

dir /b /a-d /o-d *.* >%temp%\0.tmp
set /p lastfile="" <%temp%\0.tmp
del %temp%\0.tmp
echo "%lastfile%"
set /a "y=!%x%"
set /a "y=~%x%"
set /a "y=-%x%"

Оператор == используется только для строчного сравнения. Кавычки необходимы если в переменной/операнде имеются пробелы.
Для арифметического сравнения необходимо использовать арифметические операторы:
EQU : Равно (=)
NEQ : Не равно (!=)
LSS : Меньше (<)
LEQ : Меньше или равно (<=)
GTR : Больше (>)
GEQ : Больше или равно (>=)
Использовать операторы, указанные в скобках, не представляется возможным, потому что, например, операторы < и > являются указателями перенаправления ввода-вывода.

Если вы много работаете с Пакетные файлы в Windows Операторы IF предоставляют очень мощный метод Чтобы добавить гибкости сценариям Твой собственный.

В этой статье вы узнаете о пяти основных типах операторов IF, которые можно использовать в Пакетный файл В Windows как выглядит правильный синтаксис и реальный пример каждого из них.

Если ты готов Для начала написания сценария , Давайте начнем!

Лучшие операторы IF для более рационального использования пакетных файлов в Windows - Windows

1. Сравните значения

Одна из основных вещей, которые вам обычно нужно сделать в сценарии пакетной обработки, – это сравнить два значения и предпринять различные действия в зависимости от результата сравнения.

Например, предположим, что вы хотите написать пакетный сценарий, который ежедневно проверяет размер жесткого диска вашего компьютера. Если он меньше 3 ГБ, вы захотите получить уведомление по электронной почте с надписью «Место на жестком диске слишком мало».

Чтобы создать сценарий, который сравнивает текущее доступное пространство на диске с лимитом, вы можете создать следующий пакетный сценарий и сохранить его как файл .bat.

@echo off
set DriveLimit=300000000
for /f "usebackq delims== tokens=2" %%x in (`wmic logicaldisk where "DeviceID='C:'" get FreeSpace /format:value`) do set FreeSpace=%%x
Echo FreeSpace="%FreeSpace%"
Echo Limit="%DriveLimit%"
If %FreeSpace% GTR %DriveLimit% (
 Echo There is enough free space.
) else (
 Echo Not enough free space.
)

WMIC Это сокращение от компонента инструментария управления Windows, который содержит множество команд, которые вы можете использовать для получения информации с вашего компьютера. Вот как это нужно ».WMIC«В этом скрипте доступное место для хранения»логический диски помещает его в переменную FreeSpace. Теперь вы можете заменить строку «Эхо Недостаточно свободного местаПо порядку блат электронная почта чтобы отправить вам уведомление.

Наконец, настройте этот сценарий как запланированную пакетную задачу в Windows, которая запускается ежедневно.

Если вы раньше не использовали блат, у нас есть статья, чтобы показать вам Как настроить bat. Не привыкли создавать запланированные задания? Мы создали статью о Как настроить запланированные задачи Windows.

2. Сравните строки

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

В следующем примере вы увидите, как проверить версию Windows с помощью Пакетная миссия. Затем вы можете сравнить это с ожидаемой версией Windows.

Некоторые варианты использования этого сценария будут необходимы для ИТ-аудита, когда вам нужно запустить быстрый сценарий и проверить, является ли ваша текущая операционная система последней, или если она нуждается в обновлении.

Вот как выглядит этот сценарий.

@echo off
for /f "tokens=4-5 delims=. " %%i in ('ver') do set VERSION=%%i.%%j
if "%version%" == "6.0" echo Windows Vista.
if "%version%" == "6.1" echo Windows 7
if "%version%" == "6.2" echo Windows 8
if "%version%" == "6.3" echo Windows 8.1
if "%version%" == "10.0" echo Windows 10.

Вот как выглядит результат этого скрипта.

Лучшие операторы IF для более рационального использования пакетных файлов в Windows - Windows

Возможность одновременного сравнения строк открывает целый список возможностей. Если вы исследуете Всю информацию вы можете получить из команды WMIC , вы увидите только количество статистических данных о компьютере, за которым вы можете следить. Вы можете использовать запланированные пакетные задачи, чтобы предупредить вас о них.

3. Проверьте, существует ли файл.

Еще одна полезная ситуация для оператора IF в пакетном файле – проверить, существует ли файл данных.

Часто пакетное задание – это просто инструмент мониторинга, который может быть запланирован для проверки новых файлов данных, поступающих в определенный каталог.

Затем пакетная задача может скопировать этот файл в другое место, где он может быть обработан, или запустить какой-либо сценарий Windows, который обрабатывает файл в выходных данных Excel.

(Раньше мы писали о том, как использовать сценарии Windows для обработки данных в файле Excel; хорошее фоновое чтение.)

Использование пакетного файла для проверки наличия файла в каталоге – это быстрый и простой шаг. Вот как выглядит этот сценарий.

@echo off
if exist c:\temp\datafile.txt (
 %WINDIR%\SysWOW64\cmd.exe
 cscript LoadToExcel.vbs
) else (
 rem file doesn't exist
)

Сравнение IF EXISTS полезно для многих вещей.

Например, если у вас есть система или приложение, которое генерирует новые журналы ошибок в определенной папке при возникновении проблемы, вы можете чаще запускать пакетную задачу, чтобы отслеживать, создаются ли новые журналы ошибок, чтобы вы могли отправить запланированное предупреждение.

4. Убедитесь, что команда не выполняется.

Это особый аспект пакетных сценариев, который очень немногие люди или ИТ-программисты используют для поиска ошибок.

:/>  Как настроить камеру ноутбук acer

Существует множество агрегированных задач, которые выполняют важные ИТ-задачи, такие как резервное копирование важных файлов или выполнение операций копирования файлов. Когда эти пакетные миссии терпят неудачу, системы терпят неудачу, и тогда люди это заметят.

Гораздо разумнее получить предупреждение, когда ваша пакетная миссия не удалась, прежде чем люди начнут это замечать. Таким образом вы можете заранее решить проблему.

Вы можете сделать это с помощью переменной % errorlevel% Что большинство приложений и команд возвращаются после запуска.

Все, что вам нужно сделать, это следовать вашей команде по команде ЕСЛИ% ОШИБКА%. Если приложение или команда возвращает ноль, значит, все в порядке. Если нет, вам нужно отправить себе оповещение по электронной почте.

@echo off
xcopy C:\somefolder E:\backupfolder
IF %ERRORLEVEL% NEQ 0 <blat command to send email>

Вам не нужно следовать маршруту электронной почты. Вы всегда можете написать журнал ошибок, который можно проверять каждое утро, или запустить второе приложение или команду, которая попытается выполнить задание другим способом. Какое бы действие вы ни хотели совершить, ЕСЛИ% ОШИБКА% Позвольте вам это сделать.

Если вы предпочитаете использовать оператор IF для проверки конкретных кодов ошибок, Windows предлагает обширное меню кодов ошибок.

5. Проверьте отсутствующие параметры.

Последний полезный оператор IF не является контрольным списком, а предназначен для проверки того, что скрипт получил соответствующие входные параметры.

Например, предположим, вы написали сценарий, который выполняет команду хсору Из входной папки в общую сетевую папку, используемую вашей командой. Пользователю просто нужно следовать имени вашего скрипта с параметрами, которые определяют его путь к профилю.

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

Вот как это выглядит.

@echo off
IF [%1]==[] (
GOTO sub_message
) ELSE (
xcopy %1 E:\backupfolder
)
GOTO eof
:sub_message
echo You forgot to specify your path.
:eof

Если вы ранее не использовали параметры в пакетных сценариях, символ процента, за которым следует число, представляет переменную параметра. %1 – первый параметр, %2 – второй параметр и так далее.

Пакетные функции могут быть мощными

Многие люди начинают использовать пакетные задачи для простых задач, которые необходимо выполнять последовательно. С помощью операторов IF можно сделать ваши сценарии более интеллектуальными.

Часто можно использовать такие продвинутые языки программирования или изучить Используйте PowerShell , чтобы выполнять многие из задач, которые вы сейчас используете в пакетных миссиях.

  • Arigato

Тема: CMD/BAT: Нахождение длины строки

Именно такой темы в коллекции нет, хотя в некоторых других темах этот вопрос косвенно подымался. Думаю, что решение данной задачи должно содержаться в коллекции.

Существуют разные способы, как найти длину строки. Рассмотрим их и проведем анализ производительности. В конечном счете выбор должен пасть на самый быстрый вариант решения.

Для замера производительности я использовал следующий шаблон:

@ echo off
setlocal enabledelayedexpansion
call :getTick
set start=%errorlevel%
for /l %%i in (1,1,100) do тут_вызов_функции
call :getTick
set /a long=%errorlevel%-start
echo %long%
pause
exit /b 0
:getTick
:: Количество сотых долей секунды, прошедших с начала дня setlocal set t=%time: =0% set /a tick=1%t:~9,2%-100+(1%t:~6,2%-100)*100+(1%t:~3,2%-100)*6000+(1%t:~0,2%-100)*360000
endlocal & exit /b %tick%

Т.е. будем запускать функцию определения длины строки 100 раз и замерять время работы. Определять будем длину переменной %Path%, в моем случае она составляет 388 символов – достаточно длинная строка.

Первый вариант решения задачи (решение в лоб):

:length
:: Нахождение длины строки
:: %1 - строка
:: Результат помещается в %errorlevel% setlocal set len=0 if "%~1"=="" goto end set str=%~1 :loop set /a len+=1 if not "!str:~%len%!"=="" goto loop :end
endlocal & exit /b %len%

Отработал за 1602, т.е. 16 секунд.

Второй вариант (записываем строку в файл, после чего определяем размер файла):

:length
:: Нахождение длины строки
:: %1 - строка
:: Результат помещается в %errorlevel% setlocal :length1 set "tempFolder=%TEMP%\%~n0.%time:~-2%.%random%" md "%tempFolder%" 2>nul || goto length1 set "tmpFile=%tempFolder%\1" <nul set /p ".=%1">"%tmpFile%" for /f %%f in ("%tmpFile%") do set /a "len=%%~zf" rd /s /q "%tempFolder%"
endlocal & exit /b %len%

Этот вариант отработал за 33, т.е. существенно меньше секунды. Идея создание временного файла взята из обсуждения в этой теме: http://forum.script-coding.com/viewtopic.php?id=7944

Чем же так плох первый вариант? Возможно это связано с циклом goto. В любом случае остановиться надо на втором варианте.

wisgest (изменено: wisgest, 2013-01-06 21:15:36)

  • wisgest

Re: CMD/BAT: Нахождение длины строки

Именно такой темы в коллекции нет, хотя в некоторых других темах этот вопрос косвенно подымался. Думаю, что решение данной задачи должно содержаться в коллекции.

По поводу второго варианта. Создание каталога, там где можно ограничится лишь файлом, представляется избыточным. Можно воспользоваться тем, что пока файл открыт на запись, любые посторонние попытки его изменения вызовут ошибку:

 :length1 set "tmpFile=%TEMP%\%~n0.%time:~-2%.%random%" ( ( <nul set /p ".=%1" for /f %%f in ("%tmpFile%") do set /a "len=%%~zf" ) >"%tmpFile%" || goto length1 del %tmpFile% >nul ) 2>nul

(и этот подход мне представляется более надёжным.)

Замеров времени я не проводил, но чисто умозрительно — должно быть чуть-чуть быстрее.

Arigato

  • Arigato

Re: CMD/BAT: Нахождение длины строки

Будет ли файл занят на протяжении всей скобки?

 ( <nul set /p ".=%1" for /f %%f in ("%tmpFile%") do set /a "len=%%~zf" ) >"%tmpFile%" || goto length1

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

wisgest (изменено: wisgest, 2013-01-07 01:22:40)

  • wisgest

Re: CMD/BAT: Нахождение длины строки

Будет ли файл занят на протяжении всей скобки?

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

Впрочем, можно проверить

(echo 123
pause>con)>tmp.txt

— не выйдя из паузы, не получится изменить/удалить tmp.txt

Схожий приём используется, например, в теме CMD/BAT: запуск единственной копии сценария.

urahangka

  • urahangka

Re: CMD/BAT: Нахождение длины строки

Мне гораздо больше нравится другой вариант скрипта:

:strLength string len
( SETLOCAL ENABLEDELAYEDEXPANSION set "str=A!%~1!" 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

З.Ы. По шаблону скорости – опережает все варианты.

alexii

  • alexii

Re: CMD/BAT: Нахождение длины строки

urahangka, приведите пример использования. У меня не выходит.

smaharbA

  • smaharbA

Re: CMD/BAT: Нахождение длины строки

скорость не знаю

echo off
call :len "dfljgkdflgljkgsdfg"
:return
call echo %len%
exit
:len (str) { set out=%~0 set out=%out:~1% set "str=%~1" setlocal ENABLEDELAYEDEXPANSION for /l %%x in (0,1,99999999999999999999) do ( call set t=!t!%%str:~%%~x,1%% if !t!==!str! set %out%=%%x & call :return ) exit /b
}

Rumata

  • Rumata

Re: CMD/BAT: Нахождение длины строки

echo off
call :len "dfljgkdflgljkgsdfg"
:return
call echo %len%
exit
:len (str) {
...
call :return
... exit /b
}

очень странный способ выхода из подпрограммы. А если понадобятся два вызова? Как выполнить выход в таком случае?

call :len "one"
call echo %len%
call :len "two"
call echo %len%

Правильный код: вместо call :return написать goto :EOF или exit /b

:/>  Как узнать модель ноутбука через cmd - Всё о компьютерах

smaharbA

  • smaharbA

Re: CMD/BAT: Нахождение длины строки

Rumata

  • Rumata

Re: CMD/BAT: Нахождение длины строки

Вот слегка модифицированный код. В чем его смысл?

echo off
call :len "one"
:return
call echo %len%
exit /b
:len (str) { set out=%~0 set out=%out:~1% set "str=%~1" setlocal ENABLEDELAYEDEXPANSION for /l %%x in (0,1,9) do ( call set t=!t!%%str:~%%~x,1%% if !t!==!str! set %out%=%%x & call :return ) exit /b
}

Вот результат его работы:

U:\tmp>echo off
2
3
4
5
6
7
8
9
ECHO is off.

smaharbA

  • smaharbA

Re: CMD/BAT: Нахождение длины строки

Вам еще учиться (без балды)

Rumata (изменено: Rumata, 2013-04-02 00:55:28)

  • Rumata

Re: CMD/BAT: Нахождение длины строки

Вам еще учиться (без балды)

Очень интересное высказывание на критику неправильного кода. Никто не совершенен. А дополнительные знания никому еще были лишними.

urahangka (изменено: urahangka, 2013-04-02 11:02:19)

  • urahangka

Re: CMD/BAT: Нахождение длины строки

urahangka, приведите пример использования. У меня не выходит.

@echo off
set str=super-puper-stroka, izmeryaem dliny.
call :strLen str dlina
echo stroka=%str%
echo length=%dlina%
pause
exit /b
:strLen stroka length
( SETLOCAL ENABLEDELAYEDEXPANSION set "str=A!%~1!" 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

urahangka (изменено: urahangka, 2013-04-02 12:08:50)

  • urahangka

Re: CMD/BAT: Нахождение длины строки

Кстати, нарыл где-то в недрах интернета функцию скрипта бинарного подсчета длины строки:

@echo off
set str=super-puper-stroka, izmeryaem dliny.
call :strlen4 str dlina
echo stroka=%str%
echo length=%dlina%
pause
exit /b
:strlen4 StrVar RtnVar -- be sure to check if the returned errorlevel is 0
( setlocal enabledelayedexpansion & set /a "}=0" if "%~1" neq "" if defined %~1 ( for %%# in (4096 2048 1024 512 256 128 64 32 16) do ( if "!%~1:~%%#,1!" neq "" set "%~1=!%~1:~%%#!" & set /a "}+=%%#" ) set "%~1=!%~1!0FEDCBA9876543211" & set /a "}+=0x!%~1:~32,1!!%~1:~16,1!" )
)
endlocal & set /a "%~2=%}%" & exit /b

З.Ы. Очень шустрый! Быстрее выложенного мной ранее где-то в 3 раза.

Лениво делать скриншоты, так что просто выложу результаты тестирования:
Исходные данные:
“деревянный” комп на winXP SP3 (Core 2 Duo  2Гц, 2 Гб оперы)
строка – длина 54 символа
цикл – 1000 раз
тики (сотые доли секунды) – перед циклом и после цикла. Результат – разница между тиками.

Вариант через временный файл:     9652 тика
Вариант, выложенный мной ранее: 1156 тика
Этот Вариант:                                   355 тиков.

Rumata

  • Rumata

Re: CMD/BAT: Нахождение длины строки

urahangka, ограничение в 4К вызвано чем – ограничением на длину строки в командной строке?

urahangka (изменено: urahangka, 2013-04-02 12:50:58)

  • urahangka

Re: CMD/BAT: Нахождение длины строки

urahangka, ограничение в 4К вызвано чем – ограничением на длину строки в командной строке?

Если память не отшибло, то стандартное ограничение строки – 1023. Насколько я понимаю данный скрипт по тестам, он подсчитывает длину строки вплоть до 8189 символов, если строка длиннее – все равно показывает длину 8189 символов.

smaharbA

  • smaharbA

Re: CMD/BAT: Нахождение длины строки

за скорость не знаю

@echo off & call :%~1 "%~2" 2> nul
set me=%~0
echo %time%
for /l %%x in (1,1,100) do call :len "sdfsdf"
echo %ERRORLEVEL%
echo %time%
exit
:len (str) { if "%~1"=="" exit /b 0 else cmd /c ""%me%" length "%~1"" exit /b %ERRORLEVEL%
}
:length (str) { set "str=%~1" setlocal ENABLEDELAYEDEXPANSION for /l %%x in (0,1,99999999999999999999) do ( call set x=!x!%%str:~%%~x,1%% if "!x!"=="!str!" set /a x=%%~x+1 & exit !x! ) exit 0
}

urahangka

  • urahangka

Re: CMD/BAT: Нахождение длины строки

XGuest (изменено: XGuest, 2013-04-07 23:56:19)

  • XGuest

Re: CMD/BAT: Нахождение длины строки

Доброго времени суток

Быстрей не видел

@echo off call :len var "строка" &:: "var" - Переменная куда вернуть значение echo Длина строки: %var%
goto :eof
:len set len=%~2 if not "%len%"=="" set /a %1+=1 & call :len %1 "%len:~1%"
goto :eof

@echo off
set VAR=Очень длинная строка
set BAK=%TMP%\%RANDOM%
>%BAK% echo.%VAR%
for %%I in (%BAK%) do set /a len=%%~zI-2
echo Длина строки: %len%
goto :eof

С наилучшими пожеланиями
XGuest

urahangka

  • urahangka

Re: CMD/BAT: Нахождение длины строки

Доброго времени суток

Быстрей не видел

К сожалению, тест показывает, что это самые долгие варианты функции. (1-й вариант более 24000 тиков, второй порядка 10000 тиков.)

Быстрее функции бинарного поиска, выложенного мной ранее, вариантов нету.

smaharbA

  • smaharbA

Re: CMD/BAT: Нахождение длины строки

а так можно ?

call :len "строка" &:: "len" - Переменная куда вернуть значение echo Длина строки: %len%

Get String Length using Windows Batch

September 13, 2012

algorithms, batch script, beginner, code, code library, implementation, programming languages, string, tricks, windows, windows command shell

Under Linux, there is a famous quote: “When there is a shell, there is a way.”, meaning that the Linux SHELL script is very powerful and in fact can do almost anything within or beyond your imagination. The Windows batch programming (with file extensions *.cmd or *.bat), on the other hand, is also capable of general tasks, however, some tricks might be required because there are sometimes no straightforward solutions. In this sense, the Linux SHELL is more powerful for example, the windows batch programming does not neither provide a straightforward switch/case nor a while statement. However, these can be emulated by multiple if-s and goto statements since the basic programming flows are combined by selection (if-s) and loops (goto-s).

@echo off
:: strlen.bat
:: https://uploadbeta.com
if [%1] EQU [] goto end
:loop	if [%1] EQU [] goto end	set _len=0	set _str=%1	set _subs=%_str%	:getlen	if not defined _subs goto result	:: remove first letter until empty	set _subs=%_subs:~1%	set /a _len+=1	goto getlen	:result	echo strlen("%1")=%_len%	shift	goto loop
:end

The idea is to remove each time the first character of the string and increment the length counter until the string is empty. The output example is given below.

strlen Get String Length using Windows Batch algorithms batch script beginner code code library implementation programming languages string tricks windows windows command shell

–EOF (The Ultimate Computing & Technology Blog) —

Last Post: Batch Programming Revisited, Chess Board Printing
Next Post: Print Big Characters using Windows Batch Programming

The Permanent URL is: Get String Length using Windows Batch (AMP Version)

CMD/BAT – Необходимо из файла считать строку и участи строки присвоить переменным