110

So the utility Diff works just like I want for 2 files, but I have a project that requires comparisons with more than 2 files at a time, maybe up to 10 at a time. This requires having all those files side by side to each other as well. My research has not really turned up anything, vimdiff seems to be the best so far with the ability to compare 4 at a time.

My question: Is there any utility to compare more than 2 files at a time, or a way to hack diff/vimdiff so it can do multiple comparisons? The files I will be comparing are relatively short so it should not be too slow.

starball
  • 20,030
  • 7
  • 43
  • 238
Javed Ahamed
  • 2,804
  • 6
  • 32
  • 41

7 Answers7

122

Displaying 10 files side-by-side and highlighting differences can be easily done with Diffuse. Simply specify all files on the command line like this:

diffuse 1.txt 2.txt 3.txt 4.txt 5.txt 6.txt 7.txt 8.txt 9.txt 10.txt

  • 1
    Wow this is awesome! Thanks for the response even late, I still needed the help. – Javed Ahamed Jul 21 '09 at 14:51
  • 2
    What is this sort of comparison called? – leeand00 Apr 21 '10 at 14:24
  • 4
    Fantastic tool; just helped me solve a vexing problem. I know it's an older answer, but thank you! – SeanKilleen Dec 21 '10 at 13:50
  • Thank you a thousand times! Helped a lot to find out small differences in a bunch of copy-pasted files. – Trass3r Apr 18 '13 at 09:02
  • Any idea how I can create a context menu Open With option to allow me to select multiple files and open them in different panes in the same tab? – roryhewitt Jan 18 '14 at 00:08
  • holy crap this tool is awesome – Matthias Aug 16 '16 at 16:19
  • @combatc2 The link is ok! – Gruber Jun 17 '18 at 18:14
  • 1
    @Gruber - I must of hit the link at a bad time - I've removed my comment – combatc2 Jun 18 '18 at 15:11
  • @combatc2 oh sorry my comment got "now" clipped out, dunno why! I was aiming more as notification rather than correction or something ;) – Gruber Jun 19 '18 at 02:24
  • 1
    Is this a graphical gui tool only? `/usr/lib/python2.7/dist-packages/gtk-2.0/gtk/__init__.py:57: GtkWarning: could not open display` – rogerdpack Jan 11 '19 at 14:02
  • 1
    @leeand00 I'm going to steal one from git, and call this an octopus diff :) – iCodeSometime Jan 31 '19 at 03:48
  • This utility does not seem to be actively maintained anymore, although occasionally someone will commit a small modification. However, memory leaks cause the app to crash pretty consistently on windows 10. I would have loved it if that not were not such a big issue. – Jereme Mar 14 '19 at 16:59
  • It's available in ubuntu repos (`sudo aptitude install diffuse`). Code is still expecting python2, though, so I had to replace the first line (`#!/usr/bin/env python`) with `#!/usr/bin/env python2` in `/usr/bin/diffuse`. – Eric Duminil Nov 03 '21 at 08:06
  • 1
    @leeand00 [k-way merging/diffing](https://en.wikipedia.org/wiki/K-way_merge_algorithm) – Sam Oct 31 '22 at 20:21
40

Vim can already do this:

vim -d file1 file2 file3

But you're normally limited to 4 files. You can change that by modifying a single line in Vim's source, however. The constant DB_COUNT defines the maximum number of diffed files, and it's defined towards the top of diff.c in versions 6.x and earlier, or about two thirds of the way down structs.h in versions 7.0 and up.

Noah Medling
  • 4,581
  • 1
  • 23
  • 18
  • vimdiff or vim -d can only do 4 files at a time at least on my computer. anyone know how to bypass this? – Javed Ahamed Jul 03 '09 at 00:50
  • I didn't notice the mention of that in the question. Updated to include instructions on changing Vim's limit. – Noah Medling Jul 03 '09 at 22:33
  • Hey, do you know how to actually get to structs.h or diff.c? I cant find the vim source code on Win or Linux. – Javed Ahamed Jul 06 '09 at 15:35
  • vim does not seem to be capable of doing directory comparisons for more than two directories, which limits the usefulness. A further limitation is that when the files are compared against each other you can only see the left side of the file, there are no scroll bars to see everything. And there is no GUI method to push changes back and forth. – Jereme Mar 14 '19 at 17:03
  • I have used this for 5 files across directories, but how to exit from the comparison shown? – Prasanta Bandyopadhyay Feb 02 '22 at 06:49
  • I found this was not limited to 4 files. (Without modifying source, I think the default is now 8?) Was annoying though exiting `:q` one file at a time, needed to know `:qa` to quit all. – benjimin Jan 30 '23 at 04:15
18

diff has built-in option --from-file and --to-file, which compares one operand to all others.

   --from-file=FILE1
          Compare FILE1 to all operands.  FILE1 can be a directory.

   --to-file=FILE2
          Compare all operands to FILE2.  FILE2 can be a directory.

Note: argument name --to-file is optional. e.g.

# this will compare foo with bar, then foo with baz .html files
$ diff  --from-file foo.html bar.html baz.html

# this will compare src/base-main.js with all .js files in git repo,
# that has 'main' in their filename or path
$ git ls-files :/*main*.js | xargs diff -u --from-file src/base-main.js
Mark Chackerian
  • 21,866
  • 6
  • 108
  • 99
Peacher Wu
  • 381
  • 2
  • 5
  • Wish I could get this to work with process substitution instead of real file paths. – Jan Kyu Peblik Jun 13 '19 at 20:44
  • 1
    @JanKyuPeblik If you use zsh, check out the =(...) form of process substitution that writes the output to a temp file and expands to the name of that temp file http://zsh.sourceforge.net/Doc/Release/Expansion.html#Process-Substitution – Eric Freese Oct 28 '19 at 21:22
1

Checkout "Beyond Compare": http://www.scootersoftware.com/

It lets you compare entire directories of files, and it looks like it runs on Linux too.

Scott Anderson
  • 988
  • 3
  • 11
  • 25
  • 1
    diff -r also compares entire directories of files, but it only ever compares the files from one driectory against the files from the other directory – reinierpost Apr 21 '10 at 14:22
  • 9
    Beyond Compare is a magnificent tool, and I use it all the time to solve merge conflicts. However it is not the right tool for this job, as it can only compare two files against eachother or against a common ancestor. – Superole Jul 27 '17 at 14:34
  • Sorry for -1, but this is about comparing many files to each other. – Manohar Reddy Poreddy Jan 05 '20 at 03:48
1

if your running multiple diff's based off one file you could probably try writing a script that has a for loop to run through each directory and run the diff. Although it wouldn't be side by side you could at least compare them quickly. hope that helped.

  • yeah but if i was comparing for example 3 files, i would want them to all diff against each of the other 2 files, since diff does that rearranging to see where they match up. – Javed Ahamed Jul 03 '09 at 16:37
  • i found this command that might help with your script, its called diff3 and supposedly its a utility to compare three files. http://linux.about.com/library/cmd/blcmdl1_diff3.htm the windows version can be found here http://gnuwin32.sourceforge.net/packages/diffutils.htm – Benjamin Neil Jul 06 '09 at 18:02
1

Not answering the main question, but here's something similar to what Benjamin Neil has suggested but diffing all files:

Store the filenames in an array, then loop over the combinations of size two and diff (or do whatever you want).

files=($(ls -d /path/of/files/some-prefix.*))     # Array of files to compare
max=${#files[@]}                                  # Take the length of that array
for ((idxA=0; idxA<max; idxA++)); do              # iterate idxA from 0 to length
  for ((idxB=idxA + 1; idxB<max; idxB++)); do     # iterate idxB + 1 from idxA to length
    echo "A: ${files[$idxA]}; B: ${files[$idxB]}" # Do whatever you're here for.
  done
done

Derived from @charles-duffy's answer: https://stackoverflow.com/a/46719215/1160428

anask
  • 335
  • 3
  • 5
  • for me works in this case : ```files=($(ls -d Uploads/*)) max=${#files[@]} echo "from;to;cnt" > multi_diff_cnt.csv for ((idxA=0; idxA> multi_diff_cnt.csv done done``` – Sanek Zhitnik Apr 24 '23 at 10:01
-2

There is a simple an good way to do this = GREP.

Depending on the size of the text you can copy and paste it, or you can redirect the input of the file to the grep command. If you make a grep -vir /path to make a reverse search or a grep -ir /path. This is my way for certification exams.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320