• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1172
  • Last Modified:

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 blat=D:\adminscripts\common\blat262\full\blat
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
0
7Souls
Asked:
7Souls
  • 18
  • 10
  • 3
  • +2
3 Solutions
 
telczj9Commented:
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.

 
0
 
7SoulsData Analyst/Database AdministratorAuthor Commented:
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..
0
 
GovvyCommented:
Can you use powershell? If so try:

(Get-ChildItem C:\foldername).Count
0
Restore individual SQL databases with ease

Veeam Explorer for Microsoft SQL Server delivers an easy-to-use, wizard-driven interface for restoring your databases from a backup. No expert SQL background required. Web interface provides a complete view of all available SQL databases to simplify the recovery of lost database

 
7SoulsData Analyst/Database AdministratorAuthor Commented:
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







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

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

It should work...
0
 
7SoulsData Analyst/Database AdministratorAuthor Commented:
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
0
 
GovvyCommented:
@dir X:\rman\This_database\BACKUPSET\2011_10_03 /b | find /c /v ""
0
 
7SoulsData Analyst/Database AdministratorAuthor Commented:
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
0
 
GovvyCommented:
FOR /F "tokens=1 delims=" %A in ('@dir Z:\Docs\US /b ^| find /c /v ""') do SET myVar=%A

echo %myVar%
0
 
7SoulsData Analyst/Database AdministratorAuthor Commented:
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
0
 
GovvyCommented:
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
0
 
7SoulsData Analyst/Database AdministratorAuthor Commented:
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
0
 
GovvyCommented:
Do you have a ' char at the end of ^| find /c /v "" and before closing bracket )
0
 
GovvyCommented:
You also need a space after delims="
0
 
7SoulsData Analyst/Database AdministratorAuthor Commented:
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
0
 
7SoulsData Analyst/Database AdministratorAuthor Commented:
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

0
 
GovvyCommented:
You need two sets of " after find /c /v and then a closing '
0
 
7SoulsData Analyst/Database AdministratorAuthor Commented:
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
0
 
7SoulsData Analyst/Database AdministratorAuthor Commented:
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


0
 
7SoulsData Analyst/Database AdministratorAuthor Commented:
Oh I forgot:

This for the backupdte variable:

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

7Souls
0
 
7SoulsData Analyst/Database AdministratorAuthor Commented:
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
0
 
telczj9Commented:
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!
0
 
7SoulsData Analyst/Database AdministratorAuthor Commented:
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
0
 
7SoulsData Analyst/Database AdministratorAuthor Commented:
Oh I forgot I have an :END of the script..
0
 
Steve KnightIT 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)
0
 
Bill PrewCommented:
@7Souls

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

~bp
0
 
7SoulsData Analyst/Database AdministratorAuthor Commented:
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
0
 
Steve KnightIT 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
0
 
7SoulsData Analyst/Database AdministratorAuthor Commented:
Thanks dragon-it, when I get some time I will try your suggestions.

7Souls
0
 
7SoulsData Analyst/Database AdministratorAuthor Commented:
Thanks everyone for your help!!

Thanks,
7Souls
0
 
Steve KnightIT ConsultancyCommented:
Thanks, glad it was of help.

Steve
0

Featured Post

Problems using Powershell and Active Directory?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

  • 18
  • 10
  • 3
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now