Batch file 计算某些字符的数量
我想编写一个批处理文件来计算file.txt中符号“(“and”)”的数量 例如,我有一个包含以下字符串的文件: "((( ( (( ((” 答案是8 但我有密码,我的答案是3:Batch file 计算某些字符的数量,batch-file,cmd,Batch File,Cmd,我想编写一个批处理文件来计算file.txt中符号“(“and”)”的数量 例如,我有一个包含以下字符串的文件: "((( ( (( ((” 答案是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 (
@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%
Windows command processor
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
的整行。在这种特殊情况下,不可能将此选项字符串括在双引号中,这需要res转义默认情况下被解释为参数字符串分隔符的空格和等号,使用插入符号^
将它们解释为文字字符
但更好的方法是使用双引号选项string“usebackq令牌=*eol=”
它也不定义行尾字符,但保留空格和水平制表符作为分隔符。因此,分配给循环变量I
的是删除前导空格/制表符后的行。这在这里很好,因为它避免了处理仅包含空格/制表符的行,还可以减少子例程中要处理的字符数
在子例程ProcessLine
中,首先从从文本文件中读取的行中删除所有双引号,因为“
可能稍后在剩余的命令行中导致执行时出现语法错误。当然,一行只包含一个或多个”
删除所有双引号后,将不再定义环境变量TextLine
,在这种情况下,该行肯定不包含要计数的括号
Next被分配给环境变量TempLine
从文本文件中读取的行(不带前导空格/制表符,也不带所有双引号),其中包含所有(
和)
从行中删除。如果模板行
等于文本行
,则该行不包含括号,因此可以立即退出子例程以减少批处理文件的执行时间
否则,当前行至少包含一个圆括号,因此有必要将剩余行中的每个字符与(
和)
进行比较以计数
要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读为每个命令显示的所有帮助页面
呼叫/?
echo/?
endlocal/?
获取/?
goto/?
如果/?
设置/?
setlocal/?
另请参见此解决方案基于一个高效的子例程,您可以使用该子例程计算所需的任何字符:
@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