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?
- 2,444
2 Answers
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
)
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
- 2,444