0

I want to count the number of lines of each text file in a given directory and store them in a variable.

Here is my code:

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

FOR /R "temp\textpipe_tmp\" %%U in (*.txt) DO (
    set "cmd=findstr /R /N "^^" "%%U" | find /C ":""
    for /f %%a in ('!cmd!') do set number=%%a
    echo %number%
)

:eof
pause

I'm not sure why it does not work but if I get rid of SET, it works:

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

FOR /R "temp\textpipe_tmp\" %%U in (*.txt) DO (
    findstr /R /N "^" "%%U" | find /C ":"
)

:eof
pause

I need the result stored in a variable.

zcalebz
  • 139
  • 1
  • 12
  • 1
    Simpler and faster method: `find /v /c "" filename.ext`, see [an example](http://stackoverflow.com/a/9473079/3959875). Also with delayed expansion use `!number!`, not `%number%` – wOxxOm Nov 24 '15 at 11:06
  • Thanks. That delayed expansion thing was the culprit. – zcalebz Nov 24 '15 at 11:27

2 Answers2

1

Another version, which does the same thing but is slightly better readable:

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /R "C:\Users\Gebruiker\Documents\ICT" %%U in (*.txt) DO (
    set lines=0
    for /f  %%A in (%%U) do (set /a lines+=1)
    echo !lines!
)
pause
Dennis van Gils
  • 3,487
  • 2
  • 14
  • 35
  • Remember that `for /F` ignores empty lines, and also lines starting with `;` (unless you change the default option `eol=;`)... – aschipfl Nov 24 '15 at 19:59
0

As @wOxxOm stated in his comment, find is the perfect choice for this task.

Supposing there is a file test.txt containing 12 lines, find /V /C "" "C:test.txt" will output something like:

---------- C:TEST.TXT: 12

So let us use a for /F loop to capture such an output and string substitution to get the text portion after :SPACE:

@echo off
setlocal EnableExtensions EnableDelayedExpansion
for /R "temp\textpipe_tmp\" %%U in ("*.txt") do (
    rem capturing the output of `find` here:
    for /F "delims=" %%A in ('find /V /C "" "%%~U"') do (
        set "NUMBER=%%~A"
        rem substituting substring `: ` and everything before by nothing:
        set "NUMBER=!NUMBER:*: =!"
    )
    rem at this point, variable `NUMBER` is available
    rem for the currently processed file in `%%~U`:
    echo !NUMBER!
)
endlocal

Note that find /V /C "" will return unexpected reslts if there are empty lines at the end of the file (one of such might not be included in the count). However, empty lines at the beginning or in between non-empty ones will be counted.


Update:

Using redirection like > "C:test.txt" find /V /C "" rather than find /V /C "" "C:test.txt" avoids the prefix ---------- C:TEST.TXT: and just returns the number of lines (like 12). With this modification no string substitution is necessary and so the code looks like this:

@echo off
setlocal EnableExtensions EnableDelayedExpansion
for /R "temp\textpipe_tmp\" %%U in ("*.txt") do (
    rem capturing the output of `find` here:
    for /F "delims=" %%A in ('^> "%%~U" find /V /C ""') do (
        set "NUMBER=%%~A"
    )
    rem at this point, variable `NUMBER` is available
    rem for the currently processed file in `%%~U`:
    echo !NUMBER!
)
endlocal

The redirection mark < needs to be escaped like ^< when being used after in in for /F.

Community
  • 1
  • 1
aschipfl
  • 33,626
  • 12
  • 54
  • 99