Created
May 16, 2015 12:07
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
:: 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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...