我想写一个批处理文件来计算文本文件每行中特定字符的出现次数。
例如,字符串\
中"aa\bb\cc\dd\"
的计数为4。
find
和findstr
仅显示包含确切字符的行数。
答案 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;装饰"并确保处理文件中的所有行) 。每条线都在管道内处理,从cmd
到find
。 cmd
实例以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