Assume I have a text file (e.g. D:\test\allfiles.txt) which contain a list of file (from ONE directory D:\targetdir\sub\)
with ot without prepended path (to this single directory). The file names can contain blanks and brackets.
On the other side I have this directory D:\targetdir\sub\ in real world with files inside.
Now I want to check two things:
1.) I want to find out all files in the text file which do NOT exist in reality
and
2.) Find out all files which do exist in reality but NOT in file list.
How can I achive this with a DOS Batch file (under Win7)?
Peter
Compare a file list in text file with existing files in dir?
Moderator: DosItHelp
Re: Compare a file list in text file with existing files in
Code: Select all
@echo off
setlocal EnableDelayedExpansion
rem Load name list from text file in "name" array
set n=0
for /F "delims=" %%a in (D:\test\allfiles.txt) do (
set /A n+=1
set "name[!n!]=%%NXa"
)
rem Load real files from dir in "file" array
set f=0
cd /D D:\targetdir\sub
for %%a in (*.*) do (
set /A f+=1
set "file[!f!]=%%a"
)
rem Merge the two arrays
set /A i=1, j=1
:mergeLoop
if %i% gtr %n% goto moreFiles
if %j% gtr %f% goto moreNames
if "!name[%i%]!" eql "!file[%j%]!" (
set /A i+=1, j+=1
) else (
if "!name[%i%]!" lss "!file[%j%]!" (
echo Name "!name[%i%]!" in text file does NOT exist in reality
set /A i+=1
) else (
echo File "!file[%j%]!" do exist in reality, but NOT in the file list
set /A j+=1
)
)
goto mergeLoop
:moreNames
for /L %%i in (%i%,1,%n%) do echo Name "!name[%i%]!" in text file does NOT exist in reality
goto :EOF
:moreFiles
for /L %%j in (%j%,1,%f%) do echo File "!file[%j%]!" do exist in reality, but NOT in the file list
The process above is called FILE MERGE and requires that the contents of the two files be in the same order. The DIR command produce a file list alphabetically ordered, so the list of names in the text file MUST also be in the same order. If it is not, a SORT command does NOT solve the problem, because the file names may or may not have the prepended path, so the file should be sorted based on the file name only, that is, the last part of each line. This constitute an entirely different problem...
Also, the names in the text file must be in the same case of the real file names. If they are not, you must include the /I option in the two IF commands that compare both names.
Re: Compare a file list in text file with existing files in
This is untested:
Code: Select all
@echo off
for /f "delims=" %%a in ('type "D:\test\allfiles.txt"') do (
if not exist "D:\targetdir\sub\%%~nxa" >>notexist-sub.txt echo %%a
)
for /f "delims=" %%a in ('dir /b /a-d "D:\targetdir\sub" ') do (
find /i "%%~nxa" <"D:\test\allfiles.txt" >nul || >>notexist-allfiles.txt echo %%a
)
Re: Compare a file list in text file with existing files in
@foxidrive - your code has a risk that a false match is possible if a file name is a substring of another file name. Also prepended path info in allfiles.txt could get in the way of the 2nd test.
I believe the fastest method is to use temporary files and FINDSTR
(untested code)
Note - you probably want the case insensitive /I option anyway, but it is critical because FINDSTR has a bug where it gives the wrong result if there are multiple literal search strings of different lengths and the /I option is not used.
Dave Benham
I believe the fastest method is to use temporary files and FINDSTR
(untested code)
Code: Select all
@echo off
pushd d:\test
::Get a version of allfiles.txt that has filenames only (no path)
(
for /f "eol=: delims=" %%F in (allfiles.txt) do echo %%~nxF
) >allfiles_mod.txt
::Get the list of files found in target directory
dir /b /a-d "d:\targetdir\sub" >targetFiles.txt
::Find files in allfiles_mod.txt that are missing from target dir
findstr /vixlg:targetFiles.txt allfiles_mod.txt >notInTarget.txt
::Find files in target dir that are missing from allfiles_mod.txt
findstr /vixlg:allfiles_mod.txt targetFiles.txt >notInAllFiles.txt
::optional cleanup
del allfiles_mod.txt
del targetFiles.txt
popd
Note - you probably want the case insensitive /I option anyway, but it is critical because FINDSTR has a bug where it gives the wrong result if there are multiple literal search strings of different lengths and the /I option is not used.
Dave Benham
Re: Compare a file list in text file with existing files in
Great. Thank you.
However there is one more problem:
When I execute the following statement from your script:
dir /b /a-d "d:\targetdir\sub" >targetFiles.txt
then file names with a special char (like german Umlaute äöü or french accents or backticks) are NOT
correctly written into the internediate file.
How can I get these file names correct into filelist?
Thank you
Peter
However there is one more problem:
When I execute the following statement from your script:
dir /b /a-d "d:\targetdir\sub" >targetFiles.txt
then file names with a special char (like german Umlaute äöü or french accents or backticks) are NOT
correctly written into the internediate file.
How can I get these file names correct into filelist?
Thank you
Peter
Re: Compare a file list in text file with existing files in
Use the Windows ANSI codepage.
Regards
aGerman
Code: Select all
:: determine the current ASCII codepage
for /f "tokens=2 delims=:" %%i in ('chcp') do set /a "oemcp=%%~ni"
:: change to ANSI
>nul chcp 1252
dir ... whatever code
:: back to ASCII
>nul chcp %oemcp%
Regards
aGerman