user304602
user304602

Reputation: 991

Batch file to count occurrences

I have a plain text file like this:

...
... TYPE: alm01, ........
...
...
...
... TYPE: almBB, ........
...
...
... TYPE: out, ......
...
... TYPE: in, ......
... TYPE: almBB, ........
... TYPE: out, ......
... TYPE: out, ......

(ellipsis is stuff from the line)

so using a batch file or cmd command (using pipes if necessary) I would like to count and output the number of occurrences of each type, from the example above, I want to output:

alm01 1
almBB 2
out 3
in 1

How can I do this?

FIRST ATTEMPT: (Not working)

@echo off
setlocal enableextensions enabledelayedexpansion

rem Configuration
set "file=test.log"

rem Clean environment
for /f "tokens=1 delims==" %%v in ('set _type_ 2^>nul') do set "%%v="

rem Search required lines
for /f "tokens=*" %%l in ('findstr "TYPE:" "%file%"') do (

    rem Now we have the whole line

    set "t=%%l"

    rem Remove the prefix of the line
    set "t=%t:*TYPE: =%"
    set "t=%t:~1%"

    rem Remove the suffix of the line (from comma to end) and 
    rem increment counter of type
    for /f "tokens=1 delims=," %%t in ('echo %t%') do set /a "_type_%%t+=1"
)

rem Enumerate find types and echo type and number of occurrences
rem The inner loop is to allow underscores inside type
for /f "tokens=1,* delims=_" %%a in ('set _type_ 2^>nul') do (
    for /f "tokens=1,2 delims==" %%v in ("%%a") do echo %%v %%w
)

rem Clean and exit
endlocal
exit /b

Upvotes: 0

Views: 1781

Answers (1)

MC ND
MC ND

Reputation: 70923

@echo off
    setlocal enableextensions disabledelayedexpansion

    rem Configuration
    set "file=plaintext.txt"

    rem Clean environment
    for /f "tokens=1 delims==" %%v in ('set _type_ 2^>nul') do set "%%v="

    rem Search required lines
    for /f "tokens=*" %%l in ('findstr "TYPE:" "%file%"') do (

        rem Now we have the whole line
        set "t=%%l"

        rem Can't handle it inside the for loop. Go out to do it
        call :handleType
    )

    rem Enumerate find types and echo type and number of occurrences
    rem The inner loop is to allow underscores inside type
    for /f "tokens=1,* delims=_" %%a in ('set _type_ 2^>nul') do (
        for /f "tokens=1,2 delims==" %%v in ("%%b") do echo %%v %%w
    )

    rem Clean and exit
    endlocal
    exit /b

:handleType
    rem Remove the prefix of the line
    set "t=%t:*TYPE: =%"
    rem Remove spaces (not needed as OP stated and giving problems)
    set "t=%t: =%"

    rem Remove the suffix of the line (from comma to end) and 
    rem increment counter of type
    for /f "tokens=1 delims=," %%t in ("%t:"=%") do set /a "_type_%%~t+=1"

    goto :EOF

EDITED

The problem is real file contains some special characters (! at least) inside lines, and those characters are expanded because the delayed expansion enabled, generating the error indicated by the OP.

To handle it, delayed expansion needs to be off, but since we are reading the file inside a for loop, to get access to the changed value of the variables delayed expansion needs to be on, so, leave it off and move lines of code for type management to a subroutine outside the for loop.

Upvotes: 2

Related Questions