38

I am very new to this. Please help me

I was trying to write a batch file program to count number of files in a folder and assign that to a variable and display it to verify that it has been stored please help me with the syntax,

thank you in advance -VK

infused
  • 24,000
  • 13
  • 68
  • 78
user1452157
  • 389
  • 1
  • 3
  • 3

11 Answers11

63

I'm going to assume you do not want to count hidden or system files.

There are many ways to do this. All of the methods that I will show involve some form of the FOR command. There are many variations of the FOR command that look almost the same, but they behave very differently. It can be confusing for a beginner.

You can get help by typing HELP FOR or FOR /? from the command line. But that help is a bit cryptic if you are not used to reading it.

1) The DIR command lists the number of files in the directory. You can pipe the results of DIR to FIND to get the relevant line and then use FOR /F to parse the desired value from the line. The problem with this technique is the string you search for has to change depending on the language used by the operating system.

@echo off
for /f %%A in ('dir ^| find "File(s)"') do set cnt=%%A
echo File count = %cnt%

2) You can use DIR /B /A-D-H-S to list the non-hidden/non-system files without other info, pipe the result to FIND to count the number of files, and use FOR /F to read the result.

@echo off
for /f %%A in ('dir /a-d-s-h /b ^| find /v /c ""') do set cnt=%%A
echo File count = %cnt%

3) You can use a simple FOR to enumerate all the files and SET /A to increment a counter for each file found.

@echo off
set cnt=0
for %%A in (*) do set /a cnt+=1
echo File count = %cnt%
InteXX
  • 6,135
  • 6
  • 43
  • 80
dbenham
  • 127,446
  • 28
  • 251
  • 390
  • How do you specify the dir in which you want to count in the first method?? – LoukMouk Aug 09 '18 at 13:56
  • 3
    @LoukMo - The answer assumes current directory. To specify a different folder, simply put the path after the DIR command. – dbenham Aug 09 '18 at 14:11
13
@echo off
setlocal enableextensions
set count=0
for %%x in (*.txt) do set /a count+=1
echo %count%
endlocal
pause

This is the best.... your variable is: %count%

NOTE: you can change (*.txt) to any other file extension to count other files.....

Alexander Vogt
  • 17,879
  • 13
  • 52
  • 68
Steve IT
  • 164
  • 1
  • 8
  • This works well, but note that files with the `System` or `Hidden` attribute (eg. `attrib +s MyFile.txt`) are counted with this script but are not listed with `dir`! – AlainD Apr 05 '20 at 14:43
  • 2
    This is conceptually identical to the 3rd option in [my answer](https://stackoverflow.com/a/11005300/1012053) from 3 years earlier. Why post an identical answer? – dbenham Feb 05 '21 at 16:37
  • @dbenham _Why post an identical answer?_ Assumedly seeking for reputation. I tend to flag such answers and give a reference to the original answer. – Andreas Jul 17 '23 at 07:28
8

The mugume david answer fails on an empty folder; Count is 1 instead of a 0 when looking for a pattern rather than all files. For example *.xml

This works for me:

attrib.exe /s ./*.xml | find /v "File not found - " | find /c /v ""

Community
  • 1
  • 1
Milan
  • 624
  • 5
  • 6
8

This might be a bit faster:

dir /A:-D /B *.* 2>nul | find /c /v ""
`/A:-D` - filters out only non directory items (files)
`/B`    - prints only file names (no need a full path request)
`*.*`   - can filters out specific file names (currently - all)
`2>nul` - suppresses all error lines output to does not count them

To build for statement you should know some details at first.

for /F %%i in ('dir /A:-D /B *.* 2^>nul ^| find /c /v ""') do set "COUNT=%%i"

The example above would work, but if you want to copy paste it into another for-expression - might not.

The for /F ... expression by default has ; character as EOL character and space+tabulation characters as line separators.

If you use a file path as input in for-expression, then you can override these characters:

for /F "eol= delims=" %%i in (";My file path") do echo.Value: %%i

Where the end of eol= might not visible here. It is just a file path invalid not printable character, in this case - code 04. In most consoles and editors (except stackoverflow itself) you can type it as:

  • press ALT
  • type 04 from numeric keypad
  • release ALT

Another issue avoid here is always reset variable you want to use before the for-expression in case if for-expression is not executed:

set FILE=undefined
for /F %%i in (";My file path") do set "FILE=%%i"
echo.FILE=%FILE%
Andry
  • 2,273
  • 29
  • 28
7

The fastest code for counting files with ANY attributes in folder %FOLDER% and its subfolders is the following. The code is for script in a command script (batch) file.

@for /f %%a in ('2^>nul dir "%FOLDER%" /a-d/b/-o/-p/s^|find /v /c ""') do set n=%%a
@echo Total files: %n%.
InteXX
  • 6,135
  • 6
  • 43
  • 80
green
  • 335
  • 2
  • 10
3

Change into the directory and;

attrib.exe /s ./*.* |find /c /v ""

EDIT

I presumed that would be simple to discover. use

Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "batchfile.bat";
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();

I run this and the variable output was holding this

D:\VSS\USSD V3.0\WTU.USSD\USSDConsole\bin\Debug>attrib.exe /s ./*.*   | find /c /v "" 13

where 13 is the file count. It should solve the issue

phuclv
  • 37,963
  • 15
  • 156
  • 475
mugume david
  • 635
  • 9
  • 18
  • The OP did not ask to count files in sub-folders, so I don't see the reason for `/s` option. The OP did ask for the result to be stored in a variable, and your code does not do that. – dbenham May 18 '13 at 16:02
1

for /F "tokens=1" %a in ('dir ^| findstr "File(s)"') do echo %a

Result:

C:\MyDir> for /F "tokens=1" %a in ('dir ^| findstr "File(s)"') do @set FILE_COUNT=%a

C:\MyDir> echo %FILE_COUNT%
4   // <== There's your answer
abelenky
  • 63,815
  • 23
  • 109
  • 159
1
FOR /f "delims=" %%i IN ('attrib.exe ./*.* ^| find /v "File not found - " ^| find /c /v ""') DO SET myVar=%%i
ECHO %myVar%

This is based on the (much) earlier post that points out that the count would be wrong for an empty directory if you use DIR rather than attrib.exe.

For anyone else who got stuck on the syntax for putting the command in a FOR loop, enclose the command in single quotes (assuming it doesn't contain them) and escape pipes with ^.

trapper_hag
  • 780
  • 9
  • 14
1

I have used a temporary file to do this in the past, like this below.

DIR /B *.DAT | FIND.EXE /C /V "" > COUNT.TXT

FOR /F "tokens=1" %%f IN (COUNT.TXT) DO (
IF NOT %%f==6 SET _MSG=File count is %%f, and 6 were expected. & DEL COUNT.TXT & ECHO #### ERROR - FILE COUNT WAS %%f AND 6 WERE EXPECTED. #### >> %_LOGFILE% & GOTO SENDMAIL
)
1

With a for loop:

FOR /F %i IN ('dir /b /a-d "%cd%" ^| find /v /c "?"') DO set /a count=%i
echo %count%

Without/avoiding for loop:

(dir /b /a-d ^| find /v /c "?") | (set /p myVar=& cmd /c exit /b %myVar%)
set count=%errorlevel%
echo %count%

Tested in Win 10 cmd

Zimba
  • 2,854
  • 18
  • 26
  • 1
    The first one is already shown, but the second one is interesting! But could be simplified to `dir /b /a-d | find /v /c "" | (set /p cnt= & cmd /c exit /b %cnt%)`. Btw to get it working in a batch file, the last part has to be changed to `cmd /c exit /b %%cnt%%` – jeb Sep 17 '21 at 21:27
  • Hehe I knew you'd like it; I haven't seen anyone do it before :) – Zimba Sep 18 '21 at 20:50
0

Solution

SET directoryToCount=C:\Users\
dir %directoryToCount% > contentsOfDir.txt
echo cat contentsOfDir.txt ^| grep File > countFiles.sh
sh countFiles.sh
del countFiles.sh
del contentsOfDir.txt

Explanation

  • In both bash and batch environments, the output of a command can be redirected to a file using the > operator.
    • For example, echo hello world > myFile.txt will produce a file named myFile.txt with hello world as its text.
  • In a bash environment, one can cat the contents of a File and grep a particular line from the file containing a specified pattern.
    • For example, cat myFile.txt | grep hello will return lines containing hello
  • If Windows Subsystems for Linux is enabled, then one can execute sh from a Command Prompt to access a linux-like environment.
  • Therefore, we can solve this by doing the following
    1. Use dir to acquire a list of files in the directory, as well as the number of files
    2. Redirect the output of dir to a file (perhaps named contentsOfDir.txt).
    3. Create a .sh file to grep for File from contentsOfDir.txt
    4. Call the .sh file from command prompt to invoke the grep
    5. Delete the .sh file
    6. Delete contentsOfDir.txt