¿Hay una herramienta de diferencia de texto en cuanto a caracteres?

Constantemente necesito comparar parejas de archivos de texto de ancho fijo que cambian en posiciones de caracteres específicas. Estos archivos suelen tener una sola línea y un número fijo de bytes, por lo que la mayoría de las herramientas de comparación marcan toda la línea como diferente, pero no especifican qué caracteres son los que desvían.

¿Existe alguna herramienta especializada para este tipo de archivos? Solo puedo encontrar herramientas de línea inteligente. No me importa la plataforma en la que se ejecutan las herramientas.

¿Qué sistema operativo?
¿Qué tipo de diferencias? ¿Reemplazos simples de caracteres o también se insertan o eliminan caracteres?

Respuestas (2)

Con un par de líneas de python puedes hacer esto:

Python está preinstalado en la mayoría de las instalaciones de OS-X y Linux, se puede instalar en el resto apt-gety está disponible para Windows.

Código de ejemplo:

#! /usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
import sys

def diffline(l1, l2):
    """ Difference a pair of lines."""
    print("A:", l1.strip())
    print("B:", l2.strip())
    delta = ["   "]
    for n in xrange(min([len(l1), len(l2)])):
        if l1[n] == l2[n]:
            delta.append(' ')
        else:
            delta.append('^')
    excess = abs(len(l1) - len(l2))
    delta.append('^' * excess)
    print("".join(delta))


def linedelta(fname1, fname2):
    """
    Compare lines in two text files and mark the position of deltas.
    """
    print("A =", fname1)
    print("B =", fname2)
    line_no = 0
    l1 = "???"
    l2 = "!!!"
    with open(fname1, 'rt') as f1:
        with open(fname2, 'rt') as f2:
            while len(l1) and len(l2):
                line_no += 1
                l1 = f1.readline()
                l2 = f2.readline()
                if l1 <> l2:
                    print("Line:", line_no)
                    diffline(l1, l2)
    if not len(l1) + len(l2):
        print("Files differ after line", line_no)

if __name__ == "__main__":
    if len(sys.argv) != 3:
        print("Usage:\n\tLineDelta.py file1 file2")
    else:
        linedelta(sys.argv[1], sys.argv[2])

Entradas de ejemplo

Prueba1.txt:

ABCABCABCABCABCABCABCABCABCABCABCABC
CBACBACBACBACBACBACBACBACBACBACBACBA
ABCABCABCABCABCABCABCABCABCABCABCABC

Prueba2.txt:

ABCABCABCABCABCABCABCABCABCABCABCABC
CBACBACBACBACBACBACBACBACBACCACBACBA
ABCABCABCABCABCABCABCABCABCABCABCABC

Prueba de funcionamiento

Correr LineDelta.py Test1.txt Test2.txtda:

A = test1.txt
B = test2.txt
Line: 2
A: CBACBACBACBACBACBACBACBACBACBACBACBA
B: CBACBACBACBACBACBACBACBACBACCACBACBA
                               ^

NB Hay posibles implementaciones más rápidas, más cortas y más elegantes, pero creo que lo anterior es probablemente más comprensible.

Meld te muestra los personajes cambiados en azul profundo:

Fusionar diferencia de caracteres

Las líneas modificadas se muestran en azul claro, por lo que puede detectar primero la línea y luego el carácter.

Gratis, código abierto.