2017-01-31 3 views
3

Ich möchte eine Batch-Datei schreiben, um die Anzahl der Vorkommen eines bestimmten Zeichens in jeder Zeile einer Textdatei zu zählen.zählen Sie ein genaues Zeichen in einer Zeile - cmd

Zum Beispiel kann die Anzahl der \ im String "aa\bb\cc\dd\" wäre 4.

Die find und die findstr nur die Anzahl der Linien, die den genauen Charakter enthalten.

+0

Mögliches Duplikat von [Schleife für jedes Zeichen in variabler Zeichenkette BATCH] (http://StackOverflow.com/questions/15004825/Looping-for-every-character-in-Variable-String-Batch) – geisterfurz007

Antwort

1

hier ist ein Weg:

@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% 
    ) 
) 

es Ihnen gefällt nennen kann:

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

nicht funktionieren mit einigen Sonderzeichen (", ~ und !)

Sie auch Ersatz verwenden können und die :strlen function

+2

Leider, gewonnen ' t korrekte Ergebnisse für eine Folge von '\\' zurückgeben. – Magoo

+0

@Magoo - aktualisiert ... – 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 

Hier ist eine Möglichkeit, bestimmte Zeichen in einer Zeichenfolge zu zählen. Es wird nicht für die üblichen Verdächtigen funktionieren.

1

Nicht ausführlich getestet, aber funktioniert mit Ihrem Beispiel.

@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 

Hier ist eine weitere Option. Ich denke nicht, dass dies mit Giftcharakteren kugelsicher ist.

@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

Sie sollten [die Quelle] (http://www.dostips.com/forum/viewtopic.php?f=3&t=6429) Ihrer zweiten Lösung ... – Aacini

+0

@Aacini, Vielen Dank. Ich habe den Link vergessen. [Linked] (http://stackoverflow.com/a/41855701/1417694) dazu neulich in dieser Frage. – Squashman

2

Sie können das folgende Skript versuchen, die Bereitstellung der Eingabezeichenfolge als (zitiert) Argument Befehlszeile:

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

jedes Zeichen Dies ersetzt durch " + SPACE gezählt werden + " und umschließt die gesamte Zeichenfolge zwischen "", so dass die Eingabezeichenfolge aa\bb\cc\dd\"aa" "bb" "cc" "dd" "" wird. Der resultierende String wird in eine for-Schleife eingespeist, die einzelne Elemente erkennt, die durchlaufen werden sollen - fünf in diesem Fall. Die Zählervariable COUNT wird mit einem Wert von -1 initialisiert. Das Ergebnis ist also nicht die Anzahl der iterierten Elemente, sondern die Trennzeichen, nämlich die in der ursprünglichen Zeichenfolge vorhandenen Zeichen \.

Dieser Ansatz schlägt fehl, wenn die Zeichenfolge ? oder * Zeichen enthält. Es würde auch fehlschlagen, wenn das zu zählende Zeichen eines der folgenden ist: ", %, =, *, ~.

2
@echo off 
setlocal 

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

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

echo %count% 

Diese Methode funktioniert einwandfrei, solange die Zeichenfolge nicht Wild-Card-Zeichen beinhalten: *?; wenn dies erforderlich ist, würde ich das gleiche npocmaka Methode verwenden, aber auf einfachere Art und Weise geschrieben:

@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! Große Vereinfachung – npocmaka

+0

Ja. Ich erinnere mich an diese Logik jetzt von einer anderen Frage. Kann mich nicht erinnern, ob das auf DosTips oder hier war. – Squashman

+0

Hallo Antonio. Habe gerade festgestellt, dass dein zweiter Code nicht funktioniert, wenn es aufeinanderfolgende Zeichen gibt. aa \ bb \\ cc \ dd \ -Dies zählt nur 4. – Squashman

1

Während langsam, können Sie versuchen, mit diesem

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

Die Eingabedatei readed wird mit findstr /n zu Holen Sie alle Zeilen in der Datei mit einem Nummern-Präfix (sowohl für die Ausgabe "Dekoration" und um sicherzustellen, dass alle Zeilen in der Datei verarbeitet werden). Jede Linie wird in einem Rohr von cmd bis find bearbeitet. Die cmd Instanz wird mit der Unicode-Ausgabe gestartet (/u). Wenn die readed Zeile also wiederholt wird, ist die Ausgabe eine Zwei-Byte-Sequenz für jedes Eingabezeichen, eines davon ein 0x0 ASCII-Zeichen. Der find Befehl sieht die 0 als einen Zeilenabschluss, so dass wir jedes Zeichen in der Eingabezeile als eine separate Zeile erhalten. Jetzt zählt der find Befehl, in wievielen Zeilen das gesuchte Zeichen passiert.

Verwandte Themen