texto - programa para comparar archivos xml
Usar ''diff''(o cualquier otra cosa) para obtener diferencias de nivel de caracteres entre archivos de texto (13)
Me gustaría usar ''diff'' para obtener una diferencia de línea entre y diferencia de caracteres. Por ejemplo, considere:
Archivo 1
abcde
abc
abcccd
Archivo 2
abcde
ab
abccc
Usando diff -u obtengo:
@@ -1,3 +1,3 @@
abcde
-abc
-abcccd
/ No newline at end of file
+ab
+abccc
/ No newline at end of file
Sin embargo, solo me muestra que hubo cambios en estas líneas. Lo que me gustaría ver es algo así como:
@@ -1,3 +1,3 @@
abcde
-ab<ins>c</ins>
-abccc<ins>d</ins>
/ No newline at end of file
+ab
+abccc
/ No newline at end of file
Entiendes mi deriva.
Ahora, sé que puedo usar otros motores para marcar / verificar la diferencia en una línea específica. Pero prefiero usar una herramienta que lo haga todo.
Aquí hay una herramienta de comparación de texto en línea: http://text-compare.com/
Puede resaltar cada char que es diferente y continúa comparando el resto.
Creo que la solución más simple es siempre una buena solución. En mi caso, el siguiente código me ayuda mucho. Espero que ayude a los demás.
#!/bin/env python
def readfile( fileName ):
f = open( fileName )
c = f.read()
f.close()
return c
def diff( s1, s2 ):
counter=0
for ch1, ch2 in zip( s1, s2 ):
if not ch1 == ch2:
break
counter+=1
return counter < len( s1 ) and counter or -1
import sys
f1 = readfile( sys.argv[1] )
f2 = readfile( sys.argv[2] )
pos = diff( f1, f2 )
end = pos+200
if pos >= 0:
print "Different at:", pos
print ">", f1[pos:end]
print "<", f2[pos:end]
Puede comparar dos archivos con la siguiente sintaxis en su terminal favorita:
$ ./diff.py fileNumber1 fileNumber2
Git tiene una palabra diff, y la definición de todos los caracteres como palabras efectivamente le da un carácter diff. Sin embargo, los cambios de nueva línea son IGNORADOS.
EJEMPLO:
Crea un repositorio como este:
mkdir chardifftest
cd chardifftest
git init
echo -e ''foobarbaz/ncatdog/nfox'' > file
git add -A; git commit -m 1
echo -e ''fuobArbas/ncat/ndogfox'' > file
git add -A; git commit -m 2
Ahora, haz git diff --word-diff=color --word-diff-regex=. master^ master
git diff --word-diff=color --word-diff-regex=. master^ master
y obtendrás:
git diff http://oi60.tinypic.com/160wpb4.jpg
Tenga en cuenta cómo se reconocen las adiciones y eliminaciones en el nivel de caracteres, mientras que las adiciones y eliminaciones de líneas nuevas se ignoran.
Es posible que también quieras probar
git diff --word-diff=plain --word-diff-regex=. master^ master
y
git diff --word-diff=porcelain --word-diff-regex=. master^ master
La difflib de Python es ace si quieres hacer esto programáticamente. Para uso interactivo, utilizo vim''s modo diff vim''s (bastante fácil de usar: solo invoque vim con vimdiff ab
). También utilicé ocasionalmente Beyond Compare , que hace prácticamente todo lo que podrías esperar de una herramienta diff.
No he visto ninguna herramienta de línea de comandos que lo haga de manera útil, pero como notas de Will, el código de ejemplo de difflib podría ayudar.
La difflib de Python puede hacer esto.
La documentación incluye un ejemplo de programa de línea de comandos para usted.
El formato exacto no es el que usted especificó, pero sería sencillo analizar el resultado del estilo ndiff o modificar el programa de ejemplo para generar su notación.
No es una respuesta completa, pero si la salida de cmp -l
no es lo suficientemente clara, puede usar:
sed ''s//(./)//1/n/g'' file1 > file1.vertical
sed ''s//(./)//1/n/g'' file2 > file2.vertical
diff file1.vertical file2.vertical
Puede usar el comando cmp
en Solaris:
cmp
Compare dos archivos, y si difieren, indica el primer byte y el número de línea donde difieren.
Puedes usar:
diff -u f1 f2 |colordiff |diff-highlight
colordiff
es un paquete de Ubuntu. Puede instalarlo usando sudo apt-get install colordiff
.
diff-highlight
es de git (desde la versión 2.9). Se encuentra en /usr/share/doc/git/contrib/diff-highlight/diff-highlight
. Puedes ponerlo en algún lugar de tu $PATH
. O consíguelo del proyecto diff-so-fancy .
Python tiene una biblioteca conveniente llamada difflib
que podría ayudar a responder su pregunta.
A continuación se encuentran dos oneliners que usan difflib
para diferentes versiones de python.
python3 -c ''import difflib, sys; /
print("".join( /
difflib.ndiff( /
open(sys.argv[1]).readlines(),open(sys.argv[2]).readlines())))''
python2 -c ''import difflib, sys; /
print "".join( /
difflib.ndiff( /
open(sys.argv[1]).readlines(), open(sys.argv[2]).readlines()))''
Estos pueden ser útiles como un alias de shell que es más fácil de mover con su .${SHELL_NAME}rc
.
$ alias char_diff="python2 -c ''import difflib, sys; print /"/".join(difflib.ndiff(open(sys.argv[1]).readlines(), open(sys.argv[2]).readlines()))''"
$ char_diff old_file new_file
Y una versión más legible para poner en un archivo independiente.
#!/usr/bin/env python2
from __future__ import with_statement
import difflib
import sys
with open(sys.argv[1]) as old_f, open(sys.argv[2]) as new_f:
old_lines, new_lines = old_f.readlines(), new_f.readlines()
diff = difflib.ndiff(old_lines, new_lines)
print ''''.join(diff)
Si mantiene sus archivos en Git, puede diferenciar entre las versiones con el diff-highlight , que mostrará diferentes líneas, con las diferencias resaltadas.
Lamentablemente, solo funciona cuando el número de líneas eliminadas coincide con el número de líneas agregadas; existe un código auxiliar para cuando las líneas no coinciden, por lo que, presumiblemente, esto podría solucionarse en el futuro.
También escribí mi propio script para resolver este problema usando el algoritmo de subsecuencia común más largo.
Se ejecuta como tal
JLDiff.py a.txt b.txt out.html
El resultado es en html con coloración roja y verde. Los archivos más grandes requieren de manera exponencial una mayor cantidad de tiempo para procesar, pero esto hace una verdadera comparación de carácter por carácter sin verificar línea por línea primero.
Salida de color de nivel de personaje
Esto es lo que puede hacer con la siguiente secuencia de comandos y diff-highlight (que es parte de git):
#!/bin/sh -eu
# Use diff-highlight to show word-level differences
diff -U3 --minimal "$@" |
sed ''s/^-//x1b[1;31m-/;s/^+//x1b[1;32m+/;s/^@//x1b[1;34m@/;s/$//x1b[0m/'' |
diff-highlight
( Respuesta de crédito a @transcilar para el resaltado sed
)
cmp -l file1 file2 | wc
Funcionó bien para mí El número más a la izquierda del resultado indica la cantidad de caracteres que difieren.