Командный процессор Windows cmd.exe
, выполняющий пакетные файлы построчно, определенно не подходит для этой задачи.Он предназначен для выполнения команд и приложений.Тем не менее, здесь есть пакетный файл, который содержит круглые скобки в текстовом файле.
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "OpenBracketCount=0"
set "CloseBracketCount=0"
for /F "usebackq tokens=* eol=" %%I in ("File.txt") do (
set "TextLine=%%I"
call :ProcessLine
)
echo Number of opening brackets: %OpenBracketCount%
echo Number of closing brackets: %CloseBracketCount%
endlocal
goto :EOF
:ProcessLine
set "TextLine=%TextLine:"=%"
if not defined TextLine goto :EOF
set "TempLine=%TextLine:(=%"
if not defined TempLine goto BracketCount
set "TempLine=%TempLine:)=%"
if "%TempLine%" == "%TextLine%" goto :EOF
:BracketCount
if "%TextLine:~0,1%" == "(" ( set /A "OpenBracketCount+=1" ) else if "%TextLine:~0,1%" == ")" set /A CloseBracketCount+=1
set "TextLine=%TextLine:~1%"
if defined TextLine goto BracketCount
goto :EOF
Команда FOR с использованием параметра /F
для обработки строк из текстового файла по умолчанию игнорируется.пустые строки и строки, начинающиеся с точки с запятой, которая используется по умолчанию для конца строки eol
, и разбивают строку на подстроки (токены) на вкладках пробелов.Можно игнорировать пустые строки, но строки с ;
в начале не следует игнорировать для подсчета скобок.
Оба нежелательных поведения при обработке строк можно отключить с помощью usebackq^ delims^=^ eol^=
, чтобы получить всю назначенную строкув переменную окружения TextLine
, указав без разделителей и без символа конца строки.Невозможно заключить эту строку параметров в двойные кавычки в этом особом случае, который требует экранирования пробелов и знаков равенства, интерпретируемых по умолчанию как разделители строк аргументов с помощью символа вставки ^
, чтобы интерпретировать их как буквенные символы.
Но лучше использовать строку параметров в двойных кавычках "usebackq tokens=* eol="
, которая также не определяет символ конца строки, но сохраняет пробел и горизонтальную табуляцию в качестве разделителей.Таким образом, переменной цикла I
присваивается строка после удаления начальных пробелов / табуляций.Это хорошо, так как позволяет избежать обработки строк, содержащих только пробелы / табуляции, и может также уменьшить количество символов для обработки в подпрограмме.
В подпрограмме ProcessLine
сначала все двойные кавычки удаляются из прочитанной строкииз текстового файла, поскольку "
может позже в остальных командных строках привести к синтаксической ошибке при выполнении.Конечно, возможно, что строка содержит только один или несколько "
, в результате чего переменная окружения TextLine
больше не определяется после удаления всех двойных кавычек, и в этом случае строка определенно не содержит скобок для подсчета.
Далее присваивается переменной окружения TempLine
строка, считываемая из текстового файла (без начальных пробелов / табуляций и без всех двойных кавычек) со всеми (
и )
, удаленными из строки.Строка не содержит круглых скобок, если TempLine
равен TextLine
, и поэтому подпрограмма может быть немедленно завершена для сокращения времени выполнения командного файла.
В противном случае текущая строка содержит хотя бы одну круглую скобкуи поэтому необходимо сравнить каждый символ оставшейся строки с (
и )
, чтобы подсчитать их.
Для понимания используемых команд и того, как они работают, откройте окно командной строки, выполните тамследующие команды и полностью прочитайте все страницы справки, отображаемые для каждой команды.
call /?
echo /?
endlocal /?
for /?
goto /?
if /?
set /?
setlocal /?
См. Также Куда возвращается GOTO: EOF?