2

I have a bunch of files in a folder that their names are like a1.txt, a6.txt, a8.txt,..and I need to count them I tried this batch file but it does not recognize * as a way to account for all numbers and does not return the correct answer.

set /a count=0
for /F "tokens=* delims= " %%i in ('dir/s/b/a-d "C:\Users\xyz\desktop\Project\a.*"') do (set /a count=count+1) 

Can you see what I am doing wrong? Thanks for your help in advance.

dbenham
  • 127,446
  • 28
  • 251
  • 390
user1594078
  • 41
  • 1
  • 2
  • 5
  • 1
    Possible duplicate of [batch file - counting number of files in folder and storing in a variable](http://stackoverflow.com/questions/11004045/batch-file-counting-number-of-files-in-folder-and-storing-in-a-variable) – phuclv Nov 29 '16 at 09:43

6 Answers6

4

You could do this in a single line

dir /a-d "C:\Users\xyz\desktop\Project\a.*" | find /C "/"

Explanation:

dir is the directory listing command. The /a starts an attribute filter and the -d tells dir to not list directories. So all files in that directory with a. as the start of the filename are piped to the find command. The find command has a built in /C option to count the lines and lines in this case are files.

Okkenator
  • 1,654
  • 1
  • 15
  • 27
2

What you're doing wrong is the wildcard for all files starting with a.

You're using dir a.* and expecting it to find files like a6.txt

Also, to handle filenames with spaces, I suggest you remove the delimiters.

set /a count=0
for /F "delims=" %%i in ('dir/s/b/a-d "C:\Users\xyz\desktop\Project\a*"') do (set /a count=count+1)

( Also listen to the other answers in terms of making your code more efficient. )

azhrei
  • 2,303
  • 16
  • 18
1

Faced with a similiar problem, I prefer to use a trick I learned from Raymond Chen, wich is to use find as a replacement for wc -l.

So the following scrit sets the batch variable count to the number of files that match patttern. Like your original script, directories are excluded from the count.

@echo off

setlocal

set count=0
set pattern=a?.txt

use dir /b %pattern% ^| find /c /v ""

for /f %%i in ('dir /b /a-d %pattern_you_are_looking_for% ^| find /c /v ""') do @call set count=%%i

echo %count%

endlocal
ixe013
  • 9,559
  • 3
  • 46
  • 77
  • Thanks I appreciate, it works for the case where I have files like a1.txt, but whenI do the same with files that a part of their name come from a text file and use the same format as set pattern=file.%%a%.?.txt and it cannot replace numbers with "?" I checked echo a"%%a and it can recognize a correctly from my text file, for instance it gives file.abc.?.txt instead of file.abc.1.txt – user1594078 Aug 13 '12 at 16:38
  • Update your question with the details, we'll see. There might be an issue with [delayed expansion in for loops](http://www.robvanderwoude.com/variableexpansion.php). – ixe013 Aug 16 '12 at 13:27
1

You have your asterisk in the wrong place. I think you intended a*.txt. But that will match any text file whose name begins with "a". It does not limit the results to text files that start with "a", followed by a number.

You can pipe the results of your DIR command to FINDSTR and use a regular expression to be more specific. The FINDSTR regex support is primitive, but it often gets the job done.

I'm going to assume you want to match names like "a1.txt", "a143.txt", but you don't want to match files like "a1b.txt" or "aba1.txt". If I got that wrong then you need to change the regex expression to match your requirements.

This regex \\a[0-9][0-9]*\.txt$ works as follows:

  • \\ is an escaped backslash, matching the last backslash before the file name
  • a matches itself of course
  • [0-9] matches a single digit (there must be at least 1)
  • [0-9]* matches 0 or more additional digits
  • \.txt$ escapes the dot and matches the ".txt" extension. The $ matches the end of the string - it will not match if additional characters follow.

The last thing to do is pipe the result of FINDSTR to FIND to let it count the number of files for you. FIND /C /V "" matches any line and the /C option gives the count of matching lines. It is more efficient than incrementing the counter in your loop.

@echo off
setlocal
set /a count=0
for /F %%N in ('dir/s/b/a-d "C:\Users\xyz\desktop\Project\a*.txt"^|findstr /ric:"\\a[0-9][0-9]*\.txt$"^|find /c /v ""') do set count=%%N
echo count=%count%
dbenham
  • 127,446
  • 28
  • 251
  • 390
1
@SetLocal enabledelayedexpansion
@for /F "tokens=1" %%a IN ('Dir "..\*.txt" /-C/S/A:-D') Do @Set number_of_files=!n2! & Set n2=%%a
@echo %number_of_files%
0

here's a little bit of a sneaky way to count:

for /f "tokens=1 usebackq" %a in (`dir a* ^| find ^"File^(s^)^"`) do set count=%a

this can be done from the command line - change to double % for a batch file

there is a lot of escaping (using ^) to stop the following characters getting interpreted as part of the batch file, instead of being passed to the command line

The command being executed is dir a* | find "File(s)" , but |,(,) and " tend to have special meanings

SeanC
  • 15,695
  • 5
  • 45
  • 66