Compare a file list in text file with existing files in dir?

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
pstein
Posts: 125
Joined: 09 Nov 2011 01:42

Compare a file list in text file with existing files in dir?

#1 Post by pstein » 01 Mar 2012 15:19

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

Aacini
Expert
Posts: 1932
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Compare a file list in text file with existing files in

#2 Post by Aacini » 01 Mar 2012 22:58

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.

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Compare a file list in text file with existing files in

#3 Post by foxidrive » 01 Mar 2012 23:27

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
)

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Compare a file list in text file with existing files in

#4 Post by dbenham » 02 Mar 2012 05:07

@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)

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

pstein
Posts: 125
Joined: 09 Nov 2011 01:42

Re: Compare a file list in text file with existing files in

#5 Post by pstein » 05 Mar 2012 11:13

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

aGerman
Expert
Posts: 4740
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Compare a file list in text file with existing files in

#6 Post by aGerman » 05 Mar 2012 12:31

Use the Windows ANSI codepage.

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

Post Reply