Well, it turns out that after creating a PowerShell script to list deleted files (part 1) and another PowerShell script to monitor for deleted, renamed or moved files (part 2), I've decided to revert to a simple, batch file instead because running a batch file is so much easier than PowerShell!
As you know, my requirement is simply to list missing files in a sequentially named list of images (off my digital camera) i.e. given files
DSCF0084.JPG must have been deleted. In the case the first and/or last file have also been deleted, then a input parameters should define the lowest and highest range instead.
So, here is
find_deleted.cmd, which can either be run with:
- no inputs - as in the scenario above,
- one input - to define the lower bound,
- two inputs - to define the lower bound and higher bound.
It's important to note that my assumption is a fixed file name convention of
xxxx is between
9999 exactly. This is very important, as I use 2 little tricks to convert strings to/from numbers:
- To convert
"0001"to a number involves concatenating
"1000"and getting the modulus (remainder after dividing) of 1000, i.e. 1000001 % 1000 = 1
- And to convert 1 back to
"0001", I check if the value is less than 10, and if so, pad it with
Another interesting trick to get the first / last file and just pulling out the numeric part is using
for /f "delims=DSCF." %%f in ('dir *.jpg /b/on'). The effect of the
delims keyword is to skip over
F and assign anything after the
. to a different variable, leaving
%%f as what's in between, i.e. the 4 digits. The
'dir *.jpg /b/on' gets the directory list sorted by name, while
'dir *.jpg /b/o-n' sorts in reverse order!
@echo off setlocal EnableDelayedExpansion if "%1"=="" ( call :find_first_file ) else ( set /a first=%1 ) if %first% leq 0 goto find_no_files if "%2"=="" ( call :find_last_file ) else ( set /a last=%2 ) if %last% leq %first% goto find_no_files echo Finding deleted photos between %first% and %last% for /l %%i in (%first%,1,%last%) do ( if %%i lss 10000 set x=%%i if %%i lss 1000 set x=0%%i if %%i lss 100 set x=00%%i if %%i lss 10 set x=000%%i if not exist "DSCF!x!.jpg" echo Deleted DSCF!x!.jpg ) echo All done! exit /b0 :find_first_file set /a first=-1 for /f "delims=DSCF." %%f in ('dir *.jpg /b/on') do ( set /a first=10000%%f %% 10000 goto :eof ) goto :eof :find_last_file set /a last=-1 for /f "delims=DSCF." %%f in ('dir *.jpg /b/o-n') do ( set /a last=10000%%f %% 10000 goto :eof ) goto :eof :find_no_files echo No DSCFxxxx.JPG photos found or invalid input! exit /b1
The script I use doesn't only list the missing files, but rather goes ahead and deletes files of the same name from my SD card. You can imagine I'd need another input parameter to specify the folder where the files reside. However, I won't share that - anything so dangerous requires too many disclaimers.