Matt
Matt

Reputation: 1032

Comparing (diff) different files with same names in lots of directories and subdirectories

I have the following directory structure in LINUX

enter image description here

In every single folder (except home), there's a file called myfile.xml

I want to compare (preferably using diff) all of the myfile.xml files. So, I want the code to automatically go in all subdirectories (as deep as it goes) and look for myfile.xml and compare them. It can also compare all of the files to 1 of them. I cannot find how to do that.

Thanks in Advance

Upvotes: 1

Views: 1236

Answers (1)

lurker
lurker

Reputation: 58244

Pick one of the xml files, say it's home/hello/myfile.xml. Then run a find (assuming you are in the folder just above home):

find home -name "myfile.xml" -print -exec diff home/hello/myfile.xml {} \; 

This will compare home/hello/myfile.xml with each of the other ones, and precede each diff output with the path name of the file being compared.

If you want a way to programmatically get the first file, you could do something like this:

basexml=$(find home -name "myfile.xml" | head -1)
find home -name "myfile.xml" -print -exec diff $basexml {} \; 

If you want a message indicating a difference before the difference output (and only if there's a difference), then you could create a small shell script as follows:

dout=$(diff $1 $2)

if [ ! "$?" = "0" ]; then
    echo "${1##*/} is different on ${1%/*} and ${2%/*}"
    echo $dout
fi

I'm not sure what the limit is on how much a shell variable can hold, so you may need a temp file:

diff $1 $2 > /tmp/$0$$

if [ ! "$?" = "0" ]; then
    echo "${1##*/} is different on ${1%/*} and ${2%/*}"
    cat /tmp/$0$$
fi

rm -f /tmp/$0$$

Let's say this script is called sdiff.sh, then your find would be:

find home -name "myfile.xml" -exec sh sdiff.sh $basexml {} \;

In the script, I named the temp file as $0$$ which is the script's name followed by its process ID. So the name will appear as /tmp/sdiff.shXXXXX where XXXXX is the process ID. In this case, I probably didn't have to be that "fancy" (we could have just called it $0.tmp or something).

Upvotes: 2

Related Questions