2017-01-31 3 views
3

Я хотел бы написать командный файл для подсчета количества вхождений определенного символа в каждой строке текстового файла.подсчет точного символа в одной строке - cmd

Например, отсчет \ в строке "aa\bb\cc\dd\" будет 4.

find и findstr показывает только количество строк, которое содержит точный характер.

+0

Возможный дубликат [Цикл для каждого символа в переменной строке BATCH] (http://stackoverflow.com/questions/15004825/looping-for-every-character-in-variable-string-batch) – geisterfurz007

ответ

1

вот один из способов:

@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

+2

К сожалению, t возвращает правильные результаты для последовательности '\\'. – Magoo

+0

@Magoo - обновлено ... – npocmaka

1
@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 

Вот способ подсчета отдельных символов в строке. Это не будет работать для обычных подозреваемых.

1

Не тестировалось экстенсивно, но работает с вашим примером.

@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 
+0

Вы должны опубликовать [источник] (http://www.dostips.com/forum/viewtopic.php?f=3&t=6429) вашего второго решения ... – Aacini

+0

@Aacini, Благодарю. Просто забыли ссылку. [Связано] (http://stackoverflow.com/a/41855701/1417694) к нему на днях в этом вопросе. – Squashman

2

Вы можете попробовать следующий сценарий, обеспечивая входную строку как (цитируемую) аргумент командной строки:

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

Это заменяет каждый символ, который будет подсчитывали " + ПРОСТРАНСТВЕ + " и охватывает всю строку между "", поэтому строка ввода aa\bb\cc\dd\ становится "aa" "bb" "cc" "dd" "". Получившаяся строка подается в цикл for, который распознает отдельные элементы для итерации через - пять в этом случае. Переменная счетчика COUNT инициализируется значением -1, поэтому результатом является не количество итерированных элементов, а разделители, а именно символы \, присутствующие в исходной строке.

Этот подход завершается с ошибкой, если строка содержит ? или * символов. Он также потерпел бы неудачу, если персонаж должен быть одним из следующих: ", %, =, *, ~.

2
@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% 
+0

ha! Большое упрощение – npocmaka

+0

Да. Я помню эту логику сейчас из другого вопроса. Не помню, было ли это на DosTips или здесь. – Squashman

+0

Привет Антонио. Просто понял, что ваш второй набор кода не работает, если есть последовательные символы. aa \ bb \\ cc \ dd \ -Это только число 4. – Squashman

1

Хотя медленно, вы можете попробовать с этим

@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 к получить все строки в файле с префиксом числа (оба для вывода «украшения» и для обеспечения обработки всех строк в файле). Каждая линия обрабатывается внутри трубы, от cmd до find. Экземпляр cmd запускается с выходом unicode (/u), поэтому, когда прочитанная строка эхом, выход будет состоять из двух байтов для каждого входного символа, один из которых - символ A12II 0x0. Команда find видит 0 в качестве терминатора линии, поэтому мы получаем каждый символ в строке ввода как одну выделенную строку. Теперь команда find подсчитывает количество строк, которые искали искомый символ.

Смежные вопросы