0

I'm trying to improve a script posted by @Tony in other question

  @Echo off
  Set _File=file.txt
  Set /a _Lines=0
  For /f %%j in ('Type %_File%^|Find "" /v /c') Do Set /a _Lines=%%j
  Echo %_File% has %_Lines% lines.

To count lines all text file in a directory and subfolders:

  @Echo off
  setlocal EnableDelayedExpansion
  Set _Dir=C:\TEST_DIR\
  Set /a _Lines=0
  for /R %_Dir% %%f in (*.*) do (
    for /f %%j in ('Type !%%f!^|Find "" /v /c') Do Set /a _Lines=!_Lines!+!%%j!
  )
  Echo %_Dir% has %_Lines% lines.
  pause

But I'm geting error: "Missing operand."

Community
  • 1
  • 1
Rama
  • 3,222
  • 2
  • 11
  • 26

2 Answers2

0

My bad, I'm was using extra !! in the sentence:

Do Set /a _Lines=!_Lines!+!%%j!

This is the working code:

@Echo off
Set _Dir=C:\TEST_DIR\
Set /a _Lines=0
for /R %_Dir% %%f in (*.*) do (
  for /f %%j in ('Find "" /v /c ^< "%%~f"') Do Set /a _Lines=_Lines+%%j
)
Echo %_File% has %_Lines% lines.
pause

[EDITED] as @aschipfl sugested

Rama
  • 3,222
  • 2
  • 11
  • 26
  • `Type !%%f!` does not make any sense, because this would treat the content of `%%f` (an iterated file) as a variable, which woud be expanded due to the surrounding `!!`, which will most likely result in an empty string; it should read `Type "%%~f"`. Alternatively, replace the entire portion `Type "%%~f"^|Find "" /v /c` by `Find "" /v /c ^< "%%~f"` (this is the way I would actually do it in order to avoid the pipe `|`). – aschipfl Dec 07 '16 at 20:42
  • Since you are not using delayed expansion any more, you do no longer need to enable it... – aschipfl Dec 08 '16 at 12:44
-1

I see a few problems.

First, as you just discovered while I was typing this, you were getting the missing operand because you were using delayed expansion on !%%j!, which you don't need. You also don't need it on Type !%%f!.... In fact, as it is, it won't work with files that have spaces. I recommend changing it to Type "%%~f"... to allow for spaces in the filename.

In general, you can discover these problems by using echo to see how the command is being interpreted. For example, duplicate this line, insert an echo after the Do. The problem becomes apparent.

for /f %%j in ('Type !%%f!^|Find "" /v /c') Do echo Set /a _Lines=!_Lines!+!%%j!

Also, beware that you'll probably get unexpected results if you use this on binary files. Consider using a different file mask (or set of file masks) instead of *.* in your for /r line. For example:

for /R %_Dir% %%f in (*.txt *.xml *.ini) do (
soja
  • 1,587
  • 8
  • 8
  • 1
    The exclamation marks around `%%j` in the `Set /a _Lines=!_Lines!+!%%j!` command line need to be removed also. Actually delayed expansion could be avoided when changing the syntax to `Set /a _Lines=_Lines+%%j` or even to `Set /a _Lines+=%%j`... – aschipfl Dec 07 '16 at 20:47
  • Regarding your first comment, aren't we saying the same thing? Agreed on the second comment. – soja Dec 07 '16 at 21:55
  • Ah yes, I didn't read carefully enough, sorry... I actually don't understand why you received a down-vote... – aschipfl Dec 08 '16 at 00:41