3

I want to compare a bunch of files in a cmd.exe batch file using fc. Unfortunately, fc reports for every pair of compared files that it didn't find any differences if there are no differences. How can I change that behaviour so that it stays silent when there are no differences and only reports if a file is indeed different?

René Nyffenegger
  • 2,097
  • 6
  • 32
  • 42

2 Answers2

1

Here's how we can check the ERRORLEVEL return values for FC. Create the following batch file:

test.cmd:

@echo off

rem create two temporary text files to compare
echo asdf > 1.txt
echo qwer > 2.txt

fc /b 1.txt 1.txt > nul 2>&1
echo Test1, errorlevel: %ERRORLEVEL%  / no differences encountered
fc 1.txt 2.txt > nul 2>&1
echo Test2, errorlevel: %ERRORLEVEL%  / different files
fc /b 1.txt 3.txt > nul 2>&1
echo Test3, errorlevel: %ERRORLEVEL%  / Cannot find at least one of the files
fc /b > nul 2>&1
echo Test4, errorlevel: %ERRORLEVEL% / Invalid syntax

rem cleanup
del 1.txt 2.txt

Run test.cmd

Result:

Test1, errorlevel: 0  / no differences encountered
Test2, errorlevel: 1  / different files
Test3, errorlevel: 2  / Cannot find at least one of the files
Test4, errorlevel: -1 / Invalid syntax

Putting it all together:

compare.cmd:

@echo off
fc /b %1 %2 > nul 2>&1

If "%ERRORLEVEL%"=="1" (
  echo different!
  rem <- do whatever you need to do here... ->
)

If "%ERRORLEVEL%"=="0" (
  echo No difference!
)

If "%ERRORLEVEL%"=="2" (
  echo File not found
)
 
If "%ERRORLEVEL%"=="-1" (
  echo Invalid syntax
)
pbarney
  • 537
  • 5
  • 19
STTR
  • 6,623
  • 2
  • 17
  • 20
1

It can be achieved by using the || construct which only executes the command on the right side if the exit status of the command on the left side is 0. Since fc's exit status is 0 if it found no differences, the cat command won't be run.

fc file1.xyz file2.xyz > c:\temp\fc.out || cat c:\temp\fc.out

If used in a batch file, a @ should be prepended so that the entired line is not echoed:

@fc %1 %2 > c:\temp\fc.out || cat c:\temp\fc.out
René Nyffenegger
  • 2,097
  • 6
  • 32
  • 42