计算一行中的确切字符 - cmd

时间:2017-01-31 14:26:12

标签: batch-file cmd

我想写一个批处理文件来计算文本文件每行中特定字符的出现次数。

例如,字符串\"aa\bb\cc\dd\"的计数为4。

findfindstr仅显示包含确切字符的行数。

6 个答案:

答案 0 :(得分:4)

您可以尝试以下脚本,将输入字符串作为(带引号)命令行参数提供:

set "STRING=%~1$"
set STRING="%STRING:\=" "%"
set /A "COUNT=-1"
for %%E in (%STRING%) do set /A "COUNT+=1"
echo Count of `\`: %COUNT%

这将替换" + SPACE + "计算的每个字符,并将整个字符串括在""之间,因此输入字符串{{ 1}}变为aa\bb\cc\dd\。生成的字符串被送入"aa" "bb" "cc" "dd" ""循环,该循环识别要迭代的各个项目 - 在这种情况下为5。计数器变量for初始化为COUNT,因此结果不是迭代项的数量,而是分隔符,即原始字符串中存在的-1个字符。

如果字符串包含\?字符,则此方法将失败。如果要计算的字符是以下之一,它也会失败:*"%=*

答案 1 :(得分:4)

@echo off
setlocal

set "string=aa\bb\cc\dd\"

set "count=-1"
for %%a in ("%string:\=" "%") do set /A count+=1

echo %count%

只要字符串不包含通配符,此方法就可以正常工作:*?;如果这是必需的,我将使用相同的npocmaka方法,但以更简单的方式编写:

@echo off
setlocal EnableDelayedExpansion

set "string=aa\bb\cc\dd\"

set "str=A%string%Z"
set "count=-1"
for /F "delims=" %%a in (^"!str:\^=^"^
% Do NOT remove this line %
^"!^") do (
  set /A count+=1
)
echo %count%

答案 2 :(得分:3)

虽然很慢,但你可以试试这个

@echo off
    setlocal enableextensions disabledelayedexpansion

    set "inputFile=input.txt"
    set "searchChar=\"

    for /f "delims=" %%a in ('
        findstr /n "^" "%inputFile%"
    ') do for /f "delims=:" %%b in ("%%~a") do (
        set "line=%%a"
        for /f %%c in ('
            cmd /u /v /e /q /c"(echo(!line:*:=!)"^|find /c "%searchChar%"
        ') do echo Line %%b has %%c characters
    )

使用findstr /n重新生成输入文件,以使用数字前缀获取文件中的所有行(输出和#34;装饰"并确保处理文件中的所有行) 。每条线都在管道内处理,从cmdfindcmd实例以unicode输出(/u)启动,因此当回显readed行时,输出将是每个输入字符的两个字节序列,其中一个是0x0 ASCII字符。 find命令将0视为行终止符,因此我们将输入行中的每个字符作为一个单独的行。现在,find命令计算搜索到的字符发生的行数。

答案 3 :(得分:2)

这是一种方式:

 @echo off
:checkCountOf string countOf [rtnrVar]
:: checks count of a substring  in a string 
setlocal EnableDelayedExpansion
set "string=aa"

set "string=%~1"
set "checkCountOf=%~2"

if "%~1" equ "" (
    if "%~3" neq "" (
        endlocal & (
           echo 0
           set "%~3=0"
           exit /b 0
        )
    ) else (
        endlocal & (
           echo 0
           exit /b 0
        )
)


)

if "!checkCountOf!" equ "$" (
    set "string=#%string%#"
    set "string=!string:%checkCountOf%%checkCountOf%=#%checkCountOf%#%checkCountOf%#!"
) else (
    set "string=$%string%$"
    set "string=!string:%checkCountOf%%checkCountOf%=$%checkCountOf%$%checkCountOf%$!"
)


set LF=^


rem ** Two empty lines are required
set /a counter=0


for %%L in ("!LF!") DO (
    for /f "delims=" %%R in ("!checkCountOf!") do ( 
        set "var=!string:%%~R%%~R=%%~L!"
        set "var=!var:%%~R=%%~L!"

        for /f "tokens=* delims=" %%# in ("!var!") do (
            set /a counter=counter+1
        )
    )
)

if !counter! gtr 0 (
    set /a counter=counter-1
)

if "%~3" neq "" (
    endlocal & (
       echo %counter%
       set "%~3=%counter%"
    )
) else (
    endlocal & (
       echo %counter%
    )
)
你可以这样称呼它:

call ::checkCountOf "/aa/b/c/" "/" slashes
echo %slashes%
exit /b %errorlevel% 

不会使用某些特殊字符("~!

您也可以使用替换和:strlen function

答案 4 :(得分:2)

@ECHO OFF
SETLOCAL
SET "String=a\b\c\\\\d"
CALL :count "%string%" \
ECHO %tally%
GOTO :EOF

:count
SETLOCAL enabledelayedexpansion
SET /a tally=0
SET "$2=%~1"
:cloop
SET "$1=%$2%"
SET "$2=!$1:*%2=!"
IF "%$1%" neq "%$2%" SET /a tally+=1&GOTO cloop
endlocal&SET tally=%tally%
GOTO :eof

这是一种计算字符串中特定字符的方法。它对通常的嫌疑人不起作用。

答案 5 :(得分:2)

未经过广泛测试,但适用于您的示例。

@ECHO OFF
SETLOCAL disabledelayedexpansion
SET "String=\a\b\c\\\\d\\"
set "previous=%string%"
set /a count=0
:loop
set "newstg=%previous:*\=%"
IF NOT "%previous%"=="%newstg%" (
    set /a count+=1
    set "previous=%newstg%"
    IF DEFINED previous goto loop
)
echo %count%
pause
GOTO :eof

这是另一个选择。我不认为这是带有毒药字符的防弹。

@ECHO OFF
SETLOCAL disabledelayedexpansion
SET "String=\\a\b\c\\\\d\\"
set i=0
set "x=%string%"
set "x=%x:\=" & set /A i+=1 & set "x=%"
echo %i%

pause