http://qs321.pair.com?node_id=648150
Category: Utility Scripts
Author/Contact Info
Description: Highlight differences between 2 files using curses highlighting, a little like "watch -d".
#!/usr/bin/perl
=head1 SYNOPSIS

  hidiff old_file new_file

=head1 DESCRIPTION

Highlight the differences between two files using curses.

The result of thinking, wouldn't it be nice to do "watch -d"
on two files.

=head1 NOTES

This is not a diff-like utility, it doesn't yet doi Longest Common Sub
+string
cleverness so an insertion or deletion will throw the rest of the line
+.
If I can figure out a way (or ways) to represent a diff in curses 
highlights and colours then I might implement it.  Ideas welcome.

hidiff currently isn't rigorous about representing all differences,
tabs, line-endings and non-ascii may cause problems.

=head1 AUTHOR

Brad Bowman, hidiff at bereft net

=head1 COPYRIGHT

Copyright (c) 2007 Brad Bowman. All rights reserved.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.

=cut
use warnings;
use strict;
use Curses;

my ($old_name, $new_name) = @ARGV;
open my $old_fh, $old_name or die "Couldn't open $old_name: $!";
open my $new_fh, $new_name or die "Couldn't open $new_name: $!";

initscr;

# Draw files
while ( !eof($old_fh) || !eof($new_fh) ) {
    my $old_line = <$old_fh>;
    my $new_line = <$new_fh>;
    chomp($old_line); 
    chomp($new_line);
    my $old_len = length($old_line);
    my $new_len = length($new_line);
    #die join ' ', map { ord($_) } split //, $new_line;
    
    my $max_len = ($old_len > $new_len) ? $old_len : $new_len;
    for my $i (0..$max_len-1) {
        my $oc = substr($old_line, $i, 1);
        my $nc = substr($new_line, $i, 1);
        if ($oc eq $nc) {
            addch($oc);
        } else {
            standout;
            addch( (ord($nc) != 0) ? $nc : ' ');
            standend;
        }
    }
    addch("\n");
}

refresh;

END {
    endwin;
}
Replies are listed 'Best First'.
Re: hidiff - char highlight diff utility
by Fletch (Bishop) on Oct 31, 2007 at 14:10 UTC
      Thanks Fletch

      I use colordiff, and sometimes vimdiff, for some tasks. I also like trac's character-wise diff within lines. A command-line tool for that would be nice, does one exist? It probably wouldn't be hard, the tricky bits are already on CPAN (Algorithm::Diff, Term::ANSIColor).

      hidiff was intended to show a file, but with it's differences to another highlighted. I think there's room to use Algorithm::Diff to improve how it does that. I need to work out what diff information to display and how, given the constraint that the "new" file is shown in it's entirety and correctly positioned. (While writing this I thought that flipping interactively from new to old may help, or be useful on it's own)

      I also just discovered "less -r" and "less -R", which make less display colordiff output usefully.

      Brad