After I copy an entire directory using xcopy, I want to verify that all the files got copied across as it often seems to fail. I'm trying to do it by looping through each file in the source directory and then checking it exists in the destination directory.
I have something that seems to work on my machine but doesn't seem to on the build machine, which is where I need it.
#echo off
set /a count=0
set /a count2=0
for /r "C:\work\DLS\built\Android_EU\data" %%f in (*) do (set /a count+=1
)
for /r "C:\work\DLS\TegraProject\DLS\assets" %%f in (*) do (set /a count2+=1
)
echo count is %count%
echo count 2 is %count2%
if %count%==%count2% echo equal
if not %count%==%count2% echo not equal
pause
if %count%==%count2% exit 0
if not %count%==%count2% exit 1
I checked manually and there are 594 files in both folders on both machines.
It's reported correctly on my machine.
On the build machine, it says there are 583 and 584 files. Is there any reason that would skip files?
Thanks,
Chris.
OK, so this seems to work- thanks for your input #foxidrive.
cd C:\work\DLS\built\Android_EU\data
dir /s /b /a-d |find /c /v "" > temp.txt
set /p count=<temp.txt
cd C:\work\DLS\TegraProject\DLS\assets\data
dir /s /b /a-d |find /c /v "" > temp.txt
set /p count2=<temp.txt
echo count is %count%
echo count 2 is %count2%
pause
if %count%==%count2% exit 0
if not %count%==%count2% exit 1
Try this: it will work up to 2^31 -1 files. :)
#echo off
set "count="
set "count2="
for /f %%a in (' dir "C:\work\DLS\built\Android_EU\data" /s /b /a-d ^|find /c /v "" ') do set count=%%a
for /f %%a in (' dir "C:\work\DLS\TegraProject\DLS\assets" /s /b /a-d ^|find /c /v "" ') do set count2=%%a
echo count is %count%
echo count 2 is %count2%
if %count% EQU %count2% echo equal
if %count% NEQ %count2% echo not equal
pause
if %count% EQU %count2% exit 0
if not %count% NEQ %count2% exit 1
Related
I'm still pretty new to batch scripting, but I'm currently working on a batch file that when launched lets me select a source and destination folder from a menu. Now in my source folder, it has sub-directories with more directories in those. I'm trying to get the batch file to take any and all files in my source folder and copy them into a single folder[Destination] without recreating the folder structure so that all of the files in my sources sub-directories are nice compiled at destination.
I've tried xcopy, robocopy, and to an extent for loops. My guess is that it'll have to be done through for loops, however I'm not sure the appropriate code I should be using for this. I would like all file types to be workable with this program and not just: jpg, jpeg, png, and gif.
Thanks for the help.
#echo off
title File Copier
color 0a
:Menu
cls
echo Main Menu
echo ---------
echo Press 1 to copy files
echo.
echo Press 2 for information
echo.
echo Press 3 to exit
echo ---------------
set /p input=
if %input% == 1 goto 1
if %input% == 2 goto 2
if %input% == 3 goto 3
goto Menu
:1
rem Source
cls
echo Please select your source folder.
echo ---------------------------------
setlocal
set "psCommand="(new-object -COM 'Shell.Application')^
.BrowseForFolder(0,'Please select your source folder:',0,0).self.path""
for /f "usebackq delims=" %%I in (`powershell %psCommand%`) do set "folder=%%I"
setlocal enabledelayedexpansion
cls
rem Destination
echo Please select your destination folder.
echo --------------------------------------
set "psCommand="(new-object -COM 'Shell.Application')^
.BrowseForFolder(0,'Please select your destination folder:',0,0).self.path""
for /f "usebackq delims=" %%I in (`powershell %psCommand%`) do set "folder2=%%I"
setlocal enabledelayedexpansion
cls
rem Source/Destination Info
Set source=!folder!
Set target=!folder2!
Echo Source: %source%
Echo Destination: %target%
echo ---------------------------------------------------------------------
:Choice
set /P c=Would you like to proceed? [Y/N]
if /I "%c%" EQU "Y" goto Yes
if /I "%c%" EQU "N" goto No
goto Choice
:Yes
cls
rem echo D | xcopy %source% %target% /-y
rem robocopy "%source%" "%destination%" *.* /E
for /d %a in (%source%) do #copy %a\*.jpg %target%
for /d %a in (%source%) do #copy %a\*.png %target%
for /d %a in (%source%) do #copy %a\*.gif %target%
pause
goto Success
:No
goto 1
:Success
cls
echo The file(s) were successfully copied.
timeout /t 4 >nul
goto Menu
Trying to do a bit of scripting to run on a windows server. The aim of the code is to check a given directory F:\TestFolder for the arrival of 1 or more files that start with IB30321* in the name.
If the file(s) have not arrived in the given directory then the script sleeps for 5mins before checking again. Once the correct file(s) have been found it exits the script.
Unfortunatly i'm getting the following error, any ideas what i can do to fix this?
FINDSTR: Bad command line
Incorrect number of files found, 1 file expected
#Echo off
cd /D "%F:\TestFolder%"
Set numfiles=0
For /f "tokens=1,* delims=:" %%A in (
'Dir /B "IB30321*" ^| findstr /n ^ '
) DO Set numfiles=%%a&Set filename=%%B
If %numfiles% equ 1 (
echo %filename% found
exit /B 0
) else (
echo "Incorrect number of files found, 1 file expected"
set numfiles=0
Timeout /T 300
)
To elaborate a bit more on my comment.
dir outputs an error message if no matching file(s) found.
findstr doesn't care what lines it counts.
suppressing error output on no find will have the do part not executed as there isn't any output.
#Echo off
cd /D "%F:\TestFolder%"
:Loop
Set numfiles=0
For /f "tokens=1,* delims=:" %%A in (
'Dir /B "IB30321*" 2^>NUL ^| findstr /n ^ '
) DO Set numfiles=%%a&Set filename=%%B
If %numfiles% equ 1 (
echo %filename% found
exit /B 0
) else (
echo "Incorrect number of files found, 1 file expected"
Timeout /T 300
)
Goto :Loop
This is my first post and I am not very skilled with batch so sorry if I really mess up.
Basically I'm working on a little batch script where once run, the user inputs a file path and line number and the specified line of the specified file will be output to the command line. I have all my variables and commands working, and the command to specify the line of the text file works fine, its just when I put my variables in it doesn't work. Now I'm guessing what I'm doing is obviously wrong since I'm new to batch, but anyway here's my code:
#echo off
color b
:top
title specified line copy tool
echo input full path to txt file
set /P filepath=">"
cls
echo what line would you like to copy?
set /P lineoriginal=">"
set /A actualline=%lineoriginal%-1
for /F "skip=%actualline% delims=" %%i in (%filepath%) do if not defined output set "output=%%i"
echo %output%
pause
See if you can see what I did wrong, thanks.
From this link Windows Batch file to echo a specific line number
you can call this function like that : Call:ReadNthLine <File> <nLine>
:ReadNthLine File nLine
FOR /F %%A IN ('^<"%~1" FIND /C /V ""') DO IF %2 GTR %%A (ECHO Error: No such line %2. 1>&2 & EXIT /b 1)
FOR /F "tokens=1* delims=]" %%A IN ('^<"%~1" FIND /N /V "" ^| FINDSTR /B /C:"[%2]"') DO ECHO.%%B
EXIT /b
And your code can be re-written like that :
#echo off
color b
:top
cls
title specified line copy tool
echo input full path to txt file
set /P "filepath=>"
cls
echo what line would you like to copy ?
set /P "nLine=>"
cls
CALL :ReadNthLine "%filepath%" %nLine%
PAUSE >NUL & goto:top
GOTO :EOF
::***************************************************************************************
:ReadNthLine File nLine
FOR /F %%A IN ('^<"%~1" FIND /C /V ""') DO IF %2 GTR %%A (ECHO Error: No such line %2. 1>&2 & EXIT /b 1)
FOR /F "tokens=1* delims=]" %%A IN ('^<"%~1" FIND /N /V "" ^| FINDSTR /B /C:"[%2]"') DO ECHO.%%B
EXIT /b
::***************************************************************************************
We are having problems when a specific files (.ost) are near to 49GB size and I'm trying to find someway to know before it happens.
I'm looking to list remotely a list and also get the size in GB instead of bytes.
The files will be always inside %userprofile%\AppData\Local\Microsoft\Outlook but sometimes cuould be also a renamed folder like %userprofile%\AppData\Local\Microsoft\Outlook_OLD
With command forfiles somehow :'D I get to show the files:
>c:\>forfiles /P %userprofile%\AppData\Local\Microsoft\ /M *.ost /S /C "cmd /c echo #path >#fsize"
Suited to me but copied from the post https://superuser.com/questions/64481/is-there-a-windows-command-line-utility-to-list-largest-files-exceeding-specific
But, I'm looking for a clean output as this code works:
#echo off
setlocal disabledelayedexpansion
set "folder=%~1"
if not defined folder set "folder=%cd%"
for /d %%a in ("%folder%\*") do (
set "size=0"
for /f "tokens=3,5" %%b in ('dir /-c /a /w /s "%%~fa\*" 2^>nul ^| findstr /b /c:" "') do if "%%~c"=="" set "size=%%~b"
setlocal enabledelayedexpansion
call :GetUnit !size! unit
call :ConvertBytes !size! !unit! newsize
echo(%%~nxa - !newsize! !unit!
endlocal
)
endlocal
exit /b
:ConvertBytes bytes unit ret
setlocal
if "%~2" EQU "KB" set val=/1024
if "%~2" EQU "MB" set val=/1024/1024
if "%~2" EQU "GB" set val=/1024/1024/1024
if "%~2" EQU "TB" set val=/1024/1024/1024/1024
> %temp%\tmp.vbs echo wsh.echo FormatNumber(eval(%~1%val%),1)
for /f "delims=" %%a in (
'cscript //nologo %temp%\tmp.vbs'
) do endlocal & set %~3=%%a
del %temp%\tmp.vbs
exit /b
:GetUnit bytes return
set byt=00000000000%1X
set TB=000000000001099511627776X
if %1 LEQ 1024 set "unit=Bytes"
if %1 GTR 1024 set "unit=KB"
if %1 GTR 1048576 set "unit=MB"
if %1 GTR 1073741824 set "unit=GB"
if %byt:~-14% GTR %TB:~-14% set "unit=TB"
endlocal & set %~2=%unit%
exit /b
From this post:
How to list all folder with size via batch file
So the idea is to input something like:
"ip address" batchfile.cmd
And output something like
fileName1.ost size 10GB
fileName2.ost size 20GB
fileName3.ost size 20GB
fileName4.ost size 20GB
Must work on XP/Vista/7. Can use batch, VBS, or whatever else anyone with the mentioned O/Ses can run (except PE).
Need to choose 15 random files, and also similarly named folders (which are in a different location), and copy them to their own folder at the same time.
I've scoured google and websites like robvanderwoude.com, and found a few close examples, but I'm too inexperienced to adapt the examples to what I need without going cross-eyed. I'd appreciate it if anyone could point me in the right direction (most efficient/easiest method to use), or some example possibly with a brief explanation I can also learn from.
Layout description:
30 files:
%~dp0\mod\store\XMLs -> %~dp0\mod\0.1.2\map\data
map01_aaa.xml
map02_bbb.xml
map03_ccc.xml
...
map60_zzz.xml
30 folders:
%~dp0\mod\store\models -> %~dp0\mod\0.1.2\sky\stuff
01_aaa_map
02_bbb_map
03_ccc_map
...
60_zzz_map
The code below is what I'm trying to adopt this to, but it only chooses 15 files/folders in order. Tried using the %random% environment var in an equation for SrcMax, but that just chooses a random amount of files and always starts with the first file.
(old code)
rem #ECHO OFF
setlocal ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS
SET SrcCount=0
SET SrcMax=15
FOR %%F IN (%~dp0\mod\store\XMLs\*.*) DO IF !SrcCount! LSS %SrcMax% (
SET /A SrcCount += 1
ECHO !SrcCount! COPY %%F %~dp0\mod\0.1.2\map\data\
COPY %%F %~dp0\mod\0.1.2\map\data\
SET FNAME=%%~nF
ECHO XCOPY /s "%~dp0\mod\store\Models\!FNAME:~3!_map" "%~dp0\mod\0.1.2\sky\stuff\!FNAME:~3!_map\"
XCOPY /s "%~dp0\mod\store\Models\!FNAME:~3!_map" "%~dp0\mod\0.1.2\sky\stuff\!FNAME:~3!_map\"
)
I believe this should work.
#echo off
setlocal enabledelayedexpansion
set XMLs_src=.\mod\store\XMLs
set XMLs_dest=.\mod\0.1.2\map\data
set maps_src=.\mod\store\models
set maps_dest=.\mod\0.1.2\sky\stuff
rmdir /q /s "%XMLs_dest%" 2>NUL
rmdir /q /s "%maps_dest%" 2>NUL
mkdir "%XMLs_dest%"
mkdir "%maps_dest%"
for /L %%X in (1,1,15) do (
call :rnd rn
call :xml !rn!
call :map !rn!
)
copy "%XMLs_dest%\*.*" "%XMLs_src%" >NUL
echo d | xcopy /q /f /e /y "%maps_dest%\*" "%maps_src%" >NUL
echo Done.
goto :EOF
:rnd
set c=0
for /d %%I in (%maps_src%\*) do set /a c+=1 >NUL
set /a %1=%RANDOM% * %c% / 32768 + 1 >NUL
goto :EOF
:xml
set c=0
for /f %%I in ('dir /b /o:n "%XMLs_src%"') do (
set /a c+=1 >NUL
if !c!==%1 (
echo %XMLs_src%\%%I -^> %XMLs_dest%\%%I
move "%XMLs_src%\%%I" "%XMLs_dest%" >NUL
goto :EOF
)
)
goto :EOF
:map
set c=0
for /f %%I in ('dir /b /o:n "%maps_src%"') do (
set /a c+=1 >NUL
if !c!==%1 (
echo %maps_src%\%%I -^> %maps_dest%\%%I
echo d | xcopy /q /f /e /y "%maps_src%\%%I" "%maps_dest%\%%I" >NUL
rmdir /q /s "%maps_src%\%%I"
goto :EOF
)
)
goto :EOF
It basically moves to prevent duplication, then copies from destination back to source to restore what was moved away.