# How do I get a count of files in a windows directory and store it in a variable for comparison with another directory

I have a script that I execute every evening and one of the things that I do is an xcopy of the backup files from a source directory to a target directory on a backup server. What I would like to do is after the xcopy is count the number of files in the source directory and store that amount in a variable and I would like to do the same for the target directory. Then compare the amounts if the target directory number of files aren't the same then send a message stating that the copy wasn't sucessful then goto end. If they are the same then logic should fall through to next if statement. So far this is what I've got so far some of you guys may have seen this before.
Thanks,
7Souls

REM Variables to store possibly changeable values and to make main script more readable
REM =============================================================================================================
set log=\\storage\backups\this_database\rman\logs\Xcopy_rman_backup_%date:~4,2%%date:~7,2%%date:~10,4%.txt
set sendto=email1@domain,email2@domain
set SubjectOK="this_database XCOPY of Online Backup was Successful"
set SubjectFail="this_database XCOPY of Online Backup not Successful"
REM =============================================================================================================
REM May be going too far?
set SendSuccess=%blat% -to %sendto% -subject %SubjectOK% -bodyf %log%
set SendFail=%blat% -to %sendto% -subject %SubjectFail% -bodyf %log%
set Backupdte=%date:~10,4%_%date:~4,2%_%date:~7,2%
REM =============================================================================================================

set xcopytime=%time:~0,2%:%time:~3,2%:%time:~6,2%
set xcopytime=%xcopytime: =0%
echo Xcopy started on %date% at %xcopytime% > %log%
echo. >> %log%

xcopy X:\rman\this_database \\storage\backups\this_database\rman /E /K /I /Y >> %log% 2>&1

echo. >> %log%
set xcopytime=%time:~0,2%:%time:~3,2%:%time:~6,2%
set xcopytime=%xcopytime: =0%
echo Xcopy ended on %date% at %xcopytime% >> \\storage\backups\this_database\rman\logs\Xcopy_rman_backup_%date:~4,2%%date:~7,2%%date:~10,4%.txt

** This is where I would like to compare the directories (And where I need the help with)
set count_source_directory = dir "X:\rman\this_database\backupsets\backupdte" | file(s) ""
set count_target_directory = dir "\\storage\backups\this_database\rman\backupsets\backupdte" | file(s) ""

if count_source_directory not equal count_target_directory (%SendFail%) goto end

set success=N
find /i "File(s) copied" %log% >NUL && (findstr /i /r /c:"^ *0 File(s) copied" %log% >NUL || set success=Y)
if %success% == Y (%SendSuccess%) ELSE (%SendFail%)

:END
###### Who is Participating?

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Commented:
I would suggest you use robocopy.exe instead of xcopy.

Robocopy is a Microsoft utility, a standalone exe, that will produce a report at the end of the task.  It will also send or create specific exit errors based on what issues it may have ran into.

Therefore you can symply look out for or implement exit code logic with differnt type of emails you may want to send.  Plus you will have a log with a report at the bottom.

telczj9,

I only wish it was that easy. I just started working at this shop and I did mentioned the use of 'robocopy' however I was told that I am to use 'XCOPY' and not 'Robocopy'. So I'm stuck I don't know if it is politics or it's ease to use by the powerful in the office.

There you have it.

Thanks for your suggestion but I've been there,
7Souls..
Commented:
Can you use powershell? If so try:

(Get-ChildItem C:\foldername).Count
Hi Govvy, not sure if I have powershell so I tried your suggestion:

(Get-Childitem X:\rman\This_database\BACKUPSET\2011_10_03).Count

and I got ".Count was unexpected at this time"
aren't there statements such as:
"for /f "tokens=*" %a in ('dir /b /s "x:\path\to\start\in\*.ext"') do @wc -l "%a"  --> that might give me the file count so that I can set it in a directory? I just don't know the correct parameters for dir command.

Thanks,
7Souls

Commented:
Thats strange as the get-childitem command works for me in local and network drives - can you test for C:\ locations...
Commented:
P.S. you will have to run this from a powershell console
Sorry Govvy, no powershell console..
Commented:
If you cd into the directory in question and run this:

@dir /b | find /c /v ""

It should work...
Hi Govvy, I tried this before and it does work(See below) but how do I get the value into a variable plus how would I "CD" into that directory can't I use the directory string in the dir part of the statement?

@dir /b | find /c /v ""
6

Thanks,
7Souls
Commented:
@dir X:\rman\This_database\BACKUPSET\2011_10_03 /b | find /c /v ""
Thanks, that works how. How would I get that in a variable so that I can compare it to another directory count?

Thanks again,
7Souls
Commented:
FOR /F "tokens=1 delims=" %A in ('@dir Z:\Docs\US /b ^| find /c /v ""') do SET myVar=%A

echo %myVar%
Govvy,

Thanks, I might have the parameters incorrect can you look and see what I did wrong?

V:\>for /f "tokens=1 delims="%A in('@dir X:\rman\DSISGTD\BACKUPSET\2011_10_03 /b
'| find /c /v "") do set backup_source_cnt =%A
in('@dir was unexpected at this time.

Thanks,
7Souls
Commented:
Try this:

FOR /F "tokens=1 delims=" %A in ('@dir X:\rman\DSISGTD\BACKUPSET\2011_10_03 /b ^| find /c /v ""') do SET myVar=%A
Something different this time it has to be where I putting the quotes can you tell me where there are double and single quotes.

V:\>FOR /F "tokens=1 delims="%A in ('@dir X:\rman\DSISGTD\BACKUPSET\2011_10_03 /
b ^| find /c /v "") do SET myVar=%A
in was unexpected at this time.

Thanks,
7Souls
Commented:
Do you have a ' char at the end of ^| find /c /v "" and before closing bracket )
Commented:
You also need a space after delims="
No, I didn't have the single quotes, I will need to try this tomorrow. Thanks for your help I will let you know first thing tomorrow.

Thanks again,
7Souls
Grovvy, Sorry I started late I tried what you asked and this is what I got:

V:\>FOR /F "tokens=1 delims=" %A in ('@dir X:\rman\DSISGTD\BACKUPSET\2011_10_04
/b ^| find /c /v"' ) do SET myVar=%A
More?

Do you know why it is asking for "more?"
Thanks,
7Souls

Commented:
You need two sets of " after find /c /v and then a closing '
Hi Govvy,

I was able to try it and what I got was a repeat of the set command. Then I followed with an echo of %myVar% and now I see the value thanks.

V:\>FOR /F "tokens=1 delims=" %A in ('@dir X:\rman\DSISGTD\BACKUPSET\2011_10_05
/b ^| find /c /v""' ) do SET myVar=%A

V:\>SET myVar=6

V:\>echo %myVar%
6

Will this disturb the flow of the script if the output comes out with the "SET'" statement repeated?

Now for the other part of my question when I am able to compare the values between the number of files in the two directories. How do I get it go to the end of the script when the values do not match?

if count_source_directory not equal count_target_directory (%SendFail%) goto end

set success=N
find /i "File(s) copied" %log% >NUL && (findstr /i /r /c:"^ *0 File(s) copied" %log% >NUL || set success=Y)
if %success% == Y (%SendSuccess%) ELSE (%SendFail%)

:END

Thanks,
7Souls
Hi Govvy,

This is the logic I'd like to use to test (See below):

FOR /F "tokens=1 delims=" %A in ('@dir X:\rman\DSISGTD\BACKUPSET\%backupdte% /b ^| find /c /v""') do SET cnt_srce_drtry=%A
FOR /F "tokens=1 delims=" %A in ('@dir Y:\devorasisgtid\rman\BACKUPSET\%backupdte% /b ^| find /c /v""') do SET cnt_trgt_drtry=%A

if not %cnt_srce_drtry% == %cnt_trgt_drtry% (%SendFail% & goto END)

:END

Is this the right way to send to the goto END statement?
Thanks,
7Souls

Oh I forgot:

This for the backupdte variable:

set backupdte=%date:~10,4%_%date:~4,2%_%date:~7,2%

7Souls
Govvy,

It's not working whenever the script hits:

FOR /F "tokens=1 delims=" %A in ('@dir X:\rman\DSISGTD\BACKUPSET\%backupdte% /b ^| find /c /v""') do SET cnt_srce_drtry=%A
I get a : \rman\DSISGTD\BACKUPSET\2011_10_05 was unexpected at this time.

Any ideas as to why this FOR statement isn't working?

Thanks,
7Souls
Commented:
7Souls,

Looking at the above line of code make sure you use two perecent signs for the variables when you use the for loop inside a script.  You only use a single percent sign for the for loop variable when you execute it directly on the command line window.

In other words, in your script substitute %A for %%A

Cheers!
Hi telczj9,

Thanks for the response i did use a variation of the command that Govvy gave and yes I was aware of the %% in a batch script what I have so far is:

And it appears to be working I will let you know when my tests get back,
7Souls

@echo off
for /f %%a in ('dir /a-d /b "X:\rman\DSISGTD\BACKUPSET\%backupdte%" ^|find /c /v ""') DO SET cnt_srce_drtry=%%a
for /f %%a in ('dir /a-d /b "\\dbstor\oraclebkup$\devorasisgtid\rman\BACKUPSET\%backupdte%" ^|find /c /v ""') DO SET cnt_trgt_drtry=%%a if not %cnt_srce_drtry% == %cnt_trgt_drtry% (%SendFail% & goto END) for /f %%a in ('dir /a-d /b "X:\rman\DSISGTD\AUTOBACKUP\%backupdte%" ^|find /c /v ""') DO SET cnt_srce_drtry=%%a for /f %%a in ('dir /a-d /b "\\dbstor\oraclebkup$\devorasisgtid\rman\AUTOBACKUP\%backupdte%" ^|find /c /v ""') DO SET cnt_trgt_drtry=%%a
if not %cnt_srce_drtry% == %cnt_trgt_drtry% (%SendFail% & goto END)

@echo on
Oh I forgot I have an :END of the script..
IT ConsultancyCommented:
You might want to look at using a little subroutine to get the count for you to make it neater / easier to read:

@echo off
setlocal enabledelayedexpansion

call :getcount "X:\rman\DSISGTD\BACKUPSET\%backupdte%" cnt_srce_drtry
call :getcount "\\dbstor\oraclebkup$\devorasisgtid\rman\BACKUPSET\%backupdte%" cnt_trgt_drtry if not %cnt_srce_drtry% == %cnt_trgt_drtry% (%SendFail% & goto END) exit /b :getcount set count=0 set variable=%~2 for /f "tokens=1" %%a in ('dir /a-d /b "%~1" ^| find /c /v "##"') do set !variable!=%%~a exit /b Or also doing a file compare of the two dirs is another option and this of course checks names match too, not just count. dir /a-d /b "X:\rman\DSISGTD\BACKUPSET\%backupdte%" > dir1.txt dir /a-d /b "\\dbstor\oraclebkup$\devorasisgtid\rman\BACKUPSET\%backupdte%" > dir2.txt
fc dir1.txt dir2.txt || (%SendFail% & goto END)

Experts Exchange Solution brought to you by

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

IT / Software Engineering ConsultantCommented:
@7Souls

In reading through this thread it looked like you had gotten something that worked.  Is there still something you need help with?

~bp
Hi everyone below is what I tested last week and it appears to be working.

@echo off

for /f %%a in ('dir /a-d /b "X:\rman\GDOEDEV\BACKUPSET\%backupdte%" ^|find /c /v ""') DO SET cnt_srce_drtry=%%a

for /f %%a in ('dir /a-d /b "\\dbstor\oraclebkup$\Devoradb\rman\BACKUPSET\%backupdte%" ^|find /c /v ""') DO SET cnt_trgt_drtry=%%a if not %cnt_srce_drtry% == %cnt_trgt_drtry% (%SendFail% & goto END) for /f %%a in ('dir /a-d /b "X:\rman\GDOEDEV\AUTOBACKUP\%backupdte%" ^|find /c /v ""') DO SET cnt_srce_drtry=%%a for /f %%a in ('dir /a-d /b "\\dbstor\oraclebkup$\Devoradb\rman\AUTOBACKUP\%backupdte%" ^|find /c /v ""') DO SET cnt_trgt_drtry=%%a

if not %cnt_srce_drtry% == %cnt_trgt_drtry% (%SendFail% & goto END)

@echo on

I apologize for the delay I did not work on it Monday. I'll come back later and pass out points.

Thanks,
7Souls
IT ConsultancyCommented:
Fair enough if you are working that's fine.  I have added the two extra dirs to compare to the other suggested formats above if you want to look at making sure the filenames are the same, not just the count:

Steve

@echo off
dir /a-d /b "X:\rman\DSISGTD\BACKUPSET\%backupdte%" > dir1.txt
dir /a-d /b "\\dbstor\oraclebkup$\devorasisgtid\rman\BACKUPSET\%backupdte%" > dir2.txt fc dir1.txt dir2.txt || (%SendFail% & goto END) dir /a-d /b "X:\rman\GDOEDEV\AUTOBACKUP\%backupdte%" > dir1.txt dir /a-d /b "\\dbstor\oraclebkup$\Devoradb\rman\AUTOBACKUP\%backupdte%" > dir2.txt
fc dir1.txt dir2.txt || (%SendFail% & goto END)

or the the other way I posted moving the for and find into a subroutine:

@echo off
setlocal enabledelayedexpansion

call :getcount "X:\rman\DSISGTD\BACKUPSET\%backupdte%" cnt_srce_drtry
call :getcount "\\dbstor\oraclebkup$\devorasisgtid\rman\BACKUPSET\%backupdte%" cnt_trgt_drtry if not %cnt_srce_drtry% == %cnt_trgt_drtry% (%SendFail% & goto END) call :getcount "X:\rman\GDOEDEV\AUTOBACKUP\%backupdte%" cnt_srce_drtry call :getcount "\\dbstor\oraclebkup$\Devoradb\rman\AUTOBACKUP\%backupdte%" cnt_trgt_drtry
if not %cnt_srce_drtry% == %cnt_trgt_drtry% (%SendFail% & goto END)

exit /b

:getcount
set count=0
set variable=%~2
for /f "tokens=1" %%a in ('dir /a-d /b "%~1" ^| find /c /v "##"') do set !variable!=%%~a
exit /b
Thanks dragon-it, when I get some time I will try your suggestions.

7Souls