13

I have a source file with two similar yet subtly different sections. I'd like to merge the two sections into one subroutine with a parameter that handles the subtle differences, but I need to be sure I'm aware of them all so I don't miss any.
What I usually do in such cases is copy each of the sections to a separate file and then use tkdiff or vimdiff to highlight the differences. Is there any way to skip the intermediate files and just diff two parts of the same file?

Nathan Fellman
  • 122,701
  • 101
  • 260
  • 319

7 Answers7

10

The linediff plugin for Vim works well for me. Visually select one section of your file and type :Linediff. Visually select the other section and type :Linediff. It will put vim in to vimdiff mode, showing only the two sections you highlighted previously. Type:LinediffReset to exit vimdiff mode.

More info:

https://unix.stackexchange.com/a/52759/32477

https://superuser.com/a/414958/199800

Community
  • 1
  • 1
Christian Long
  • 10,385
  • 6
  • 60
  • 58
6

KDiff3 is open source and available on several platforms including Win32 and Linux.

It has the "manual alignment" feature discussed by Gishu about Beyond Compare (which by the way I haven't been using personally but is considered a great tool by many people I know).

manual alignment example See this answer for more examples.

Community
  • 1
  • 1
Stéphane Bonniez
  • 4,577
  • 3
  • 21
  • 16
4

i chose to rework @ordnungswidrig's answer into a bash function (i was only interested in the differences from a single file, but this could easily be changed to handle two different files...):

# find differences within a file giving start and end lines for both sections
function diff_sections {
  local fname=`basename $1`;
  local tempfile=`mktemp -t $fname`;
  head -$3 $1 | tail +$2 > $tempfile && head -$5 $1 | tail +$4 | diff -u $tempfile - ;
  rm $tempfile;
}

you call the function like so... diff_sections path/to/file 464 483 485 506

Alexander Bird
  • 38,679
  • 42
  • 124
  • 159
stephen
  • 41
  • 1
4

I use Beyond Compare.
It allows you to select a line on each side and say 'Align Manually'. This should work just fine for you.

Gishu
  • 134,492
  • 47
  • 225
  • 308
  • Thanks! I normally work in Linux but can access my files on NFS from my windows machine using Samba. I'll try that out. Are there any tools that are native to Linux out there that do the same? – Nathan Fellman Jan 12 '09 at 08:22
  • From a bit of googling, it seems BC v3 is available for Linux. As someone posted "BC is worthing booting a windows box for" :) http://www.scootersoftware.com/moreinfo.php?zz=kb_linux – Gishu Jan 12 '09 at 08:55
  • 1
    Align manually works well if the sections are sufficiently close but I find that it can sometimes be tedious to keep it from matching that one line and then skipping giant sections of text to realign the file with itself. However it doesn't need files explicitly, you could just copy and paste (with `ctrl-shift-v`) into a new "Text Compare" tab. (BC is by far the best file differencing tool I've used.) – dash-tom-bang Dec 11 '12 at 00:40
1

Any diff tool that lets you manually adjust the alignment will do the job. Diffuse (http://diffuse.sourceforge.net/) is my favourite and it also lets you manually adjust the alignment.

0

If you can describe the start and end of the sections to compore with a regex you can use the following:

sh -c 't=`mktemp`; cat "$0" | grep -e "$2" -A10000 | grep -e "$3" -B 10000 > $t; cat "$1" | grep -e "$2" -A10000 | grep -e "$3" -B 10000 | diff -u $t - ; rm $t' firstfile secondfile "section start" "section end"

As an alternative you if you want to describe the section by line number you can do:

sh -c 't=`mktemp`; cat "$0" | head -$3 |tail +$2 > $t; cat "$1" | head -$5 | tail +$4 | diff -u $t - ; rm $t' first second 4 10 2 8

4 10 2 8 is the start and end line number for the section to consider from the first file and the second file.

You can either save the snippets a shell scripts or as aliases.

ordnungswidrig
  • 3,140
  • 1
  • 18
  • 29
0

Emacs has ediff-regions-wordwise for this -- you can take two buffers (or just one) and select a region in each, which ediff will then show for comparison.

user117529
  • 663
  • 8
  • 16