计算某些字符的数量

时间:2018-09-29 11:26:59

标签: batch-file cmd

我想编写一个批处理文件以计算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

2 个答案:

答案 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 /?

另请参阅Where does GOTO :EOF return to?