0

I have a folder in which there are a bunch of various kinds of text files. The filenames are constructed so that there's a main body and a date in the filename, for example:

AAA_20150630.txt 
AAA_20150629.txt
BBB_20150630.txt
CCC_20150630.txt
CCC_20150701.txt 

Now I want to count how many files there are for each type of file, so that in this case the desired result would be:

AAA 2
BBB 1
CCC 2

I also have another text file, filelist.txt, that lists all possible types, ie.

AAA
BBB
CCC

I'm trying to build a CMD script that would loop through the rows of filelist.txt and count the occurrances of each type of file in the folder.

So far, I've been following the advice in this question, succesfully building a script for counting how many times a single type of file appears (%source_dir% is my folder that has been set earlier on):

set count=0
for /f %%k in ('dir /b /a-d %source_dir%\AAA_* ^| find /c /v ""') do set count=%%k 
echo number of AAA files = %count%

However, I ran into a problem when trying to build another for-loop around this one in order to go through all the types of file listed in filelist:

for /f %%i in (%filelist%) do (
    set count=0
    for /f %%j in ('dir /b /a-d %source_dir%\%%i_* ^| find /c /v ""') do set count=%%j
    echo number of %%i files = %count%
)

This code does not work: it loops through all the rows, but it only counts the actual number for the first item in %filelist%, and then returns that result for all consecutive ones.

Why does this happen and how can I fix it?

Community
  • 1
  • 1
Juha K
  • 324
  • 2
  • 10

2 Answers2

0

You need delayed expansion with ! to use variables inside loops and ifs:

@echo off
setlocal EnableDelayedExpansion
for /f %%i in (%filelist%) do (
    set count=0
    for /f %%j in ('dir /b /a-d !source_dir!\%%i_* ^| find /c /v ""') do set count=%%j
    echo number of %%i files = !count!
)
pause
Dennis van Gils
  • 3,487
  • 2
  • 14
  • 35
  • Ahh I see, thank you! I actually already had delayed expansion set earlier, but hadn't figured out the exclamation marks. Rookie mistake! – Juha K Jan 05 '16 at 10:18
0

Here's a bit simpler alternative.

@echo off
setlocal

set "sourcedir=path\to\some\folder"

for /f %%I in (filelist.txt) do (
    for %%A in (%sourcedir%\%%I*) do set /a count[%%I] += 1
)

set count

It should also be a bit more efficient.

rojo
  • 24,000
  • 5
  • 55
  • 101
  • Nice, thank you. The extra efficiency is achieved by not having to execute that separate "find" command? I did notice my original script was a bit slow. However, as my filelist.txt is extremely unlikely to ever have more than ~30 entries, we're talking about mere seconds. If someone else does something similar with a bigger list, this is obviously a better way of doing it. – Juha K Jan 07 '16 at 06:31
  • It's more efficient both because it doesn't have to execute `find` and because `for` is faster than `for /f`. – rojo Jan 07 '16 at 13:34