我想编写一个批处理文件以计算file.txt中符号“(”和“)”的数量
例如,我的文件带有以下字符串: “((( ((( ((“
答案为8。
但是我有代码,我的答案是3:
gene63 36.5827588427 60.4479292958 2.96931186147
gene27 60.3394147135 36.6094868906 3.05109839589
gene092 52.9186527107 33.9127855692 13.1685617201
gene444 1.05338342277 79.6017484363 19.344868141
答案 0 :(得分:1)
此解决方案基于一个有效的子例程,您可以使用该子例程来计算所需的任何字符:
@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
答案 1 :(得分:0)
逐行执行批处理文件的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
使用选项/F
的命令 FOR 使用文本文件中的行进行处理时,默认情况下会忽略空行以及以分号开头的行,分号是行尾选项{{1 }},并在空格标签上将行拆分为子字符串(令牌)。可以忽略空行,但是在计数括号时不应忽略开头带有eol
的行。
可以使用;
来禁用两种不必要的行处理行为,方法是不指定分隔符,也不指定行尾字符,从而将整行分配给环境变量usebackq^ delims^=^ eol^=
。在这种特殊情况下,该选项字符串不可能用双引号引起来,这需要转义由默认字符解释为参数字符串分隔符的空格和等号,并用尖号字符TextLine
解释为文字字符。
但是更好的方法是使用双引号的选项字符串^
,它也没有定义行尾字符,但保留空格和水平制表符作为分隔符。因此,分配给循环变量"usebackq tokens=* eol="
的是删除前导空格/制表符后的行。这样做很好,因为它避免了仅包含空格/制表符的行,并且还可以减少子例程中要处理的字符数。
首先在子例程I
中,从文本文件读取的行中删除所有双引号,因为ProcessLine
稍后可能在其余命令行中导致执行时出现语法错误。当然,很可能一行仅包含一个或多个"
,导致在删除所有双引号后不再定义环境变量"
,在这种情况下,该行肯定不包含要计数的括号。 / p>
接下来,将从文本文件中读取的行(没有前导空格/制表符,并且没有所有双引号)分配给环境变量TextLine
,并从行中删除所有TempLine
和(
。如果)
等于TempLine
,则该行不包含括号,因此可以立即退出子例程以减少批处理文件的执行时间。
否则,当前行至少包含一个圆括号,因此有必要将其余行的每个字符与TextLine
和(
进行比较。
要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。
)
call /?
echo /?
endlocal /?
for /?
goto /?
if /?
set /?