Skip to content

Instantly share code, notes, and snippets.

@deanrather
Created May 16, 2015 12:07
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save deanrather/b6e3f8600cb9071ff300 to your computer and use it in GitHub Desktop.
Save deanrather/b6e3f8600cb9071ff300 to your computer and use it in GitHub Desktop.
Windows Batch Script to list files contained in one folder but not another
:: directory-compare.bat
:: Lists files existing in one directory, but not the other
:: Usage: \path\to\directory-compare.bat \path\to\one-dir \path\to\other-dir
:: Don't display the commands
@ECHO OFF
REM Due to some obscure reason, batch sees :: as an attempt to access a drive named ":"
REM under some circumstances.
REM So, I'll be using the inelegant "REM" statement for comments hereforth
REM http://stackoverflow.com/questions/19843849
REM http://stackoverflow.com/questions/11269338
REM Psuedocode:
REM
REM For each file in the larger directory
REM Add it's filename and path to arrays
REM
REM For each file in the smaller directory
REM If there is no matching filename in the larger directory
REM display the file's path
REM Check Windows version
IF NOT "%OS%"=="Windows_NT" GOTO Syntax
REM Enable delayed variable expansion
SETLOCAL ENABLEDELAYEDEXPANSION
REM Check command line arguments
IF "%~1"=="" GOTO Syntax REM Arg 1 must be provided
IF "%~2"=="" GOTO Syntax REM Arg 2 must be provided
IF NOT EXIST "%~f1.\" GOTO Syntax REM Arg 1 must be a directory
IF NOT EXIST "%~f2.\" GOTO Syntax REM Arg 2 must be a directory
REM Navigate to the big folder
PUSHD "%~f2" >NUL 2>&1 || GOTO Syntax
REM %2 is the 2nd arg passed in
REM %~f2 accesses that variable but parses it in a particular way
REM f gets the dirname, i.e. the directory of the file (or the directory itself)
REM http://stackoverflow.com/a/3433012/14966
REM loop through each file, recursively
FOR /r %%A IN (*) DO (
REM %%A is the name of each file, including full path
REM ECHO %%~nxA
REM ECHO %%A
REM %%~nxA displays %%A as a file[n]ame plus e[x]tension
REM http://stackoverflow.com/a/3433012/14966
REM Increment the counter
set /A i+=1
REM SET's /A param is required to perform calculations
REM http://ss64.com/nt/set.html
REM Add the filename to the list of filenames
set filenames[!i!]=%%~nxA
REM We're using !i! instead of %i% because the parenthesis create a new scope where the variable no longer exists
REM http://stackoverflow.com/questions/16852503/
REM Add the file's path to the list of paths
set paths[!i!]=%%A
)
REM Set the number of files in the big folder (i.e. the length of the array)
set n=%i%
REM for /L %%i in (1,1,%n%) do echo !filenames[%%i]!
REM Return to previous directory
POPD
REM Navigate to the big folder
PUSHD "%~f1" >NUL 2>&1 || GOTO Syntax
REM loop through each file, recursively
FOR /r %%A IN (*) DO (
SET _found=no
SET filename=%%~nxA
SET pathname=%%A
REM Need to explicitly define these as variables here, so that we can access them within
REM the inner scope using the !scope breaking things! below
REM Check whether this file (from the smaller dir) exists in the bigger dir
REM Loop through each of the filenames from the big directory (not paths, just filename)
REM Array Usage Example: http://stackoverflow.com/a/9449767/14966
for /L %%i in (1,1,%n%) do (
REM If the filename from the local file exists in the larger dir
REM set the _found variable, so that we know not to list this file
IF !filenames[%%i]!==!filename! (
SET _found=yes
REM ECHO !pathname!
REM ECHO !paths[%%i]!
)
)
REM ECHO ========= %%A
REM ECHO ========= Found: [!_found!]
REM List files which exist in the smaller directory, but not the larger
if !_found!==no ECHO %%A
)
REM Return to previous directory
POPD
:Clean up
ENDLOCAL
GOTO:EOF
:Syntax
ECHO.
ECHO directory-compare.bat
ECHO Lists files existing in one directory, but not the other
ECHO Usage: \path\to\directory-compare.bat \path\to\one-dir \path\to\other-dir
ECHO.
ECHO Written by Dean Rather
ECHO http://deanrather.com
ECHO.
ECHO Thanks to:
ECHO - Rob van der Woude -- http://www.robvanderwoude.com
IF "%OS%"=="Windows_NT" ENDLOCAL
IF "%OS%"=="Windows_NT" EXIT /B 1
@deanrather
Copy link
Author

This is by far the largest Batch script I've ever written. It was very educational and I certainly would not recommend it.
If you ever think "I'll just throw together a quick batch script!" don't. use some other language. This would have been done in 10 minutes and 5 lines of code with any other language.
I've added comments all over the place 'cause I'll surely use this as a reference should I ever want to do another batch script...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment