4

A shell script which shows differences in multiple files in two different directories and also possibly create an output file including where all mismatches were found.

Condition

  1. File dir1/file1 compare only with dir2/file1 (similarly for other files - file2 compare with file2)

  2. If any changes found: status should be "Miss-match FOUND in file file1 for example" and same thing should do for all other files as well and write a all of the results into a one file

Thanks in advance

Al Lelopath
  • 6,448
  • 13
  • 82
  • 139
user3750136
  • 69
  • 1
  • 5

2 Answers2

6

Use the diff command. Using the -r flag you can compare folders recursively:

diff -ur dir1 dir2

The output will be in a format which the patch command understands. You can save it in a file and apply those changes to dir1 using

diff -ur dir1 dir2 > my.patch
cd dir1
patch -p1 < ../my.patch
hek2mgl
  • 152,036
  • 28
  • 249
  • 266
  • `#!/bin/bash diff -ur /tmp/testr/adir1 /tmp/test/adir2 >my.patch cd /tmp/anwar/adir1 patch -p1<../my.patch bash-3.2$ bash files-compare patch: **** Only garbage was found in the patch input` – user3750136 Nov 14 '16 at 18:24
  • It should be patch -p2 in that case – hek2mgl Nov 14 '16 at 18:27
  • thanks - just tried with patch -p2 with same results - not sure why. – user3750136 Nov 14 '16 at 18:45
  • I am more interested in seeing those files where mis-match found ( file size or if there count differences as well) – user3750136 Nov 14 '16 at 18:48
  • The output from `diff` can be changed and formatted. You need to go through `man diff` and play around with those options. – hek2mgl Nov 14 '16 at 18:53
0

If you deal with text files and want to just see the differences, I would customize the diff output, as hek2mgl suggested. But if you want more control, for example to execute some commands after finding different files or you must compare binary files, you may utilize find and cmp.
Below is the sample, which you may customize:

#!/bin/bash
IFS_SAVE="$IFS"
IFS=$'\x0a'

for f in $(find dir1 -type f -printf "%f\n"); do {
    f1="dir1/$f"
    f2="dir2/$f"
    cmp --quiet "$f1" "$f2"
    check=$?
    if [ $check -eq 0 ] ; then
        echo -e "OK: $f"
    elif [ $check -eq 1 ] ; then
        echo -en "Mismatch FOUND in files: "
        filesize1=$(stat --printf="%s" "$f1" )
        filesize2=$(stat --printf="%s" "$f2" )
        echo "$f1" size:"$filesize1" "$f2" size:"$filesize2" check:"$check" 
        #you may put diff ... or anything else here
    else 
        echo "cannot compare files, probably $f2 is missing"
    fi
} ; done
IFS="$IFS_SAVE"

Depending on your situation (if filenames do not contain spaces, there are no missing files, etc.) you may omit some parts - this was just tailored from a larger script.

dr_agon
  • 323
  • 2
  • 8
  • thanks for your suggestions - I tried running this where I am trying to compare two directories however I am getting some error not sure where is the problem - I know I do have files in dir2 but it's still erroring off dir2 dir `bash-3.2$ ./file-comp-latest cannot compare files, probably dir2/file2 is missing cannot compare files, probably dir2/file9 is missing cannot compare files, probably dir2/file1 is missing cannot compare files, probably dir2/file3 is missing` – user3750136 Nov 15 '16 at 15:42
  • I have checked the script on test data before posting, so it is OK. Now, you must find out why it behaves like that with your data. Try to understand the flow of the program. The output means that `cmp` throws an error. Remove the `--quiet` switch. Add some `echo` statements before to see what is in `$f1` and `$f2`. Run the `cmd` statements directly from terminal with the same parameters. Go on. – dr_agon Nov 15 '16 at 17:02
  • ok. great it works for me now. Thanks a lot for your help. However there are slightly change in requirement which I am trying to accomplish but not sure how to go about this. here is situation: I will need to pass four arguments to the script as follows: – user3750136 Nov 17 '16 at 15:16