0

In a batch file I want to count lines in files in a few directories and use the line count in an environment variable later in that batch. For example, consider I have the following files:

Directory1\update.log       (1 line)
Directory2\update.log       (2 lines)
Directory3\update.log       (3 lines)

This is the batch file I'm using:

for /d %%d in (*.*) do (
   echo Processing %%d
   cd %%d
   for /f %%c in ('find /v /c "" ^< update.log') do set count=%%c
   echo Count is %count%
   cd ..
)

Now I open a new command window and call that batch. The results of the first call are:

Processing Directory1
Count is
Processing Directory2
Count is
Processing Directory3
Count is

And any subsequent call in the same command window results in

Processing Directory1
Count is 3
Processing Directory2
Count is 3
Processing Directory3
Count is 3

What am I doing wrong here?

  • Don't have time to write up the full answer, but look up "delayed expansion". Short version you need to enable that, then use ! instead of % inside the parentheses. – Ryan Bemrose Feb 20 '15 at 09:28

2 Answers2

1

Following the comment of @RyanBemrose I found this question which lead me to the following working code:

setlocal ENABLEDELAYEDEXPANSION

for /d %%d in (*.*) do (
   echo Processing %%d
   cd %%d
   for /f %%c in ('find /v /c "" ^< update.log') do set count=%%c
   echo Count is !count!
   cd ..
)
Community
  • 1
  • 1
1

The problem is that cmd expands %count% as it reads the loop. This leads cmd to execute the following loop:

echo Processing %d
cd %d
for /f %c in ('find /v /c "" ^< update.log') do set count=%c
echo Count is
cd ..

If you are not into delayed expansion, another trick is to quote %count% with extra %s, and then to force expansion of that during execution of the loop will a call.

for /d %%d in (*.*) do (
    echo Processing %%d
    cd %%d
    for /f %%c in ('find /v /c "" ^< update.log') do set count=%%c
    call echo Count is %%count%%
    cd ..
)

Ugh (for cmd in general).

bobbogo
  • 14,989
  • 3
  • 48
  • 57