Reputation: 991
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
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