How to check if two files are identical, within a Windows shell script?

2

I am writing a shell script using the Windows NT(ish) shell scripting language. (My computer has Windows 10.) I want to check if two text files are identical. If the files are identical, I want my script to do one thing. If the files are not identical, I want my script to do something else. The script should not pause to ask for manual entry of more data.

The "Similar Questions" list has questions about Macintosh and bash shell scripts. It also has an answer about running fc or comp from the command line, which provide a verbose output. Unfortunately, fc does not return a result to %errorlevel%, and comp asks for manual data entry instead of simply exiting.

I have a copy of Tim Hill's book on Windows NT shell scripting. Page 216 has the following line of code, where %D1% and %D2% are directories, but I do not know how to modify it to work on just a single pair of files:

for /f "tokens=*" %%I in ('fc /b %D1%\*.* %D2%\*.* ^| find /v "Comparing" ^| find /v "FC: no*"') do (set /a ERRORS+=1) & (echo %%I)

Jasper

Posted 2017-07-07T02:20:25.383

Reputation: 123

1

Is PowersShell an option? Because if it is, you might find Get-FileHash useful. I once wrote a script that removes the duplicate files from the second path; however, one can easily replace that with another command: https://superuser.com/questions/1219008/find-and-delete-duplicated-files-in-different-disks-and-directories/1219012#1219012

– flolilo – 2017-07-07T02:27:23.990

@flolilolilo -- No, the rest of the script is already in the Windows NT shell scripting language. Is there a trivial way to wrap a PowerShell script to be called by a Windows NT shell script? – Jasper – 2017-07-07T02:35:48.277

What happens if you take Mr Hill's line and replace %D1%\*.* and %D2%\*.* with single file names, or variables representing single file names? – Jeff Zeitlin – 2017-07-07T02:43:22.467

@JeffZeitlin -- Running fc /b a.txt b.txt | find /v "Comparing" | find /v "FC: no*" from the command line does not produce a simple yes/no answer, but does pollute stdout. – Jasper – 2017-07-07T03:05:51.640

Answers

7

You can use this code:

fc /b file1 file2 > nul
if errorlevel 1 goto files_differ
[files are the same, do something here]

:files_differ
[files are not the same, do something here]

An errorlevel of 1 is returned if the files are NOT identical.

An errorlevel of 2 means that one of the files is missing.

> nul is used to hide the output of the command

Alternatively, you can use Busybox for Windows and check if the file hashes are the same.

rahulatschool

Posted 2017-07-07T02:20:25.383

Reputation: 86

> nul only eats stdout; it still pollutes stderr when a file is missing. 1> nul 2> nul eats both stdout and stderr. – Jasper – 2017-07-07T03:46:44.843

@Jasper Indeed! – rahulatschool – 2017-07-07T05:47:05.760

#@Jasper Or >nul 2>&1 :) – DavidPostill – 2017-07-07T09:23:07.567