Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running diff and have it stop on a difference

Tags:

linux

bash

diff

I have a script running that is checking multiples directories and comparing them to expanded tarballs of the same directories elsewhere.

I am using diff -r -q and what I would like is that when diff finds any difference in the recursive run it will stop running instead of going through more directories in the same run.

All help appreciated!

Thank you

@bazzargh I did try it like you suggested or like this.

for file in $(find $dir1 -type f); 
do if [[ $(diff -q $file ${file/#$dir1/$dir2}) ]]; 
then echo differs: $file > /tmp/$runid.tmp 2>&1; break; 
else echo same: $file > /dev/null; fi; done 

But this only works with files that exist in both directories. If one file is missing I won't get information about that. Also the directories I am working with have over 300.000 files so it seems to be a bit of overhead to do a find for each file and then diff.

I would like something like this to work, with and elif statement that checks if $runid.tmp contains data and breaks if it does. I added 2> after the first if statement so stderr is sent to the $runid.tmp file.

for file in $(find $dir1 -type f); 

do if [[ $(diff -q $file ${file/#$dir1/$dir2}) ]] 2> /tmp/$runid.tmp; 

then echo differs: $file > /tmp/$runid.tmp 2>&1; break; 

elif [[ -s /tmp/$runid.tmp ]]; 

then echo differs: $file >> /tmp/$runid.tmp 2>&1; break;

else echo same: $file > /dev/null; fi; done

Would this work?

like image 530
xterrez Avatar asked Mar 21 '23 12:03

xterrez


2 Answers

You can do the loop over files with 'find' and break when they differ. eg for dirs foo, bar:

for file in $(find foo -type f); do if [[ $(diff -q $file ${file/#foo/bar}) ]]; then   echo differs: $file; break; else echo same: $file; fi; done

NB this will not detect if 'bar' has directories that do not exist in 'foo'.

Edited to add: I just realised I overlooked the really obvious solution:

diff -rq foo bar | head -n1
like image 53
bazzargh Avatar answered Mar 28 '23 14:03

bazzargh


It's not 'diff', but with 'awk' you can compare two files (or more) and then exit when they have a different line.

Try something like this (sorry, it's a little rough)

awk '{ h[$0] = ! h[$0] } END { for (k in h) if (h[k]) exit }' file1 file2

Sources are here and here.

edit: to break out of the loop when two files have the same line, you may have to do the loop in awk. See here.

like image 40
philshem Avatar answered Mar 28 '23 16:03

philshem