посчитать количество определенных символов - PullRequest
0 голосов
/ 29 сентября 2018

Я хотел бы написать командный файл для подсчета количества символов "(" и ")" в file.txt

Например, у меня есть файл с этой строкой: "(((((((("

Ответ будет 8.

Но у меня есть код и мой ответ 3:

@echo off 

set "f=file.txt" 
set "sk9=(" 
set "sk0=)" 

set /a "k9=0" 
set /a "k0=0" 



for /f "usebackq delims="  %%a in ("%f%") do for %%i in (%%a) do ( 
if "%%i"=="%sk9%" ( 
        set /a k9=k9+1 
      ) )

echo %k9% 

Ответы [ 2 ]

0 голосов
/ 29 сентября 2018

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

@echo off
setlocal

call :CountChar "(" test.txt LeftParen=
echo Number of left parens = %LeftParen%
goto :EOF


:CountChar char file result=
setlocal DisableDelayedExpansion

rem Create a copy of input file with the desired characters removed

rem Process all file lines in %%a FOR replaceable parameter
(for /F "usebackq delims=" %%a in ("%~2") do (
   set "line=%%a"
   rem Enable status to expand line variable
   setlocal EnableDelayedExpansion
   rem Output the variable without the desired character
   echo(!line:%~1=!
   endlocal
rem Store previous smaller output in another file
)) > smallerFile.txt

rem Get the size difference between both files
for %%a in ("%~2") do for %%b in (smallerFile.txt) do (
   rem Store the result in third subroutine parameter
   endlocal & set /A "%~3=%%~Za-%%~Zb"
)
del smallerFile.txt
exit /b
0 голосов
/ 29 сентября 2018

Командный процессор 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?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...