it-swarm.com.de

Verwenden Sie "diff" (oder irgendetwas anderes), um Unterschiede zwischen den Textdateien auf Zeichenebene zu erhalten

Ich möchte 'diff' verwenden, um einen Linienunterschied zwischen und einen Zeichenunterschied zu erhalten .__Betrachten Sie zum Beispiel:

Datei 1

abcde
abc
abcccd

Datei 2

abcde
ab
abccc

Mit diff -u bekomme ich:

@@ -1,3 +1,3 @@
 abcde
-abc
-abcccd
\ No newline at end of file
+ab
+abccc
\ No newline at end of file

Es zeigt mir jedoch nur, dass es Änderungen in diesen Zeilen gab. Was ich gerne sehen würde, ist so etwas wie:

@@ -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

Du bekommst meinen Drift.

Jetzt weiß ich, dass ich andere Engines verwenden kann, um den Unterschied in einer bestimmten Zeile zu markieren. Aber ich würde lieber ein Werkzeug verwenden, das alles macht.

59
VitalyB

Git hat einen Word-Diff. Wenn Sie alle Zeichen als Wörter definieren, erhalten Sie effektiv einen Character-Diff. Newline-Änderungen werden jedoch ignoriert.

BEISPIEL:

Erstellen Sie ein Repository wie folgt:

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

Jetzt mache git diff --Word-diff=color --Word-diff-regex=. master^ master und du bekommst:

git diff http://oi60.tinypic.com/160wpb4.jpg

Beachten Sie, wie sowohl Hinzufügungen als auch Löschungen auf Zeichenebene erkannt werden, während Hinzufügungen und Löschungen von Zeilenumbrüchen ignoriert werden.

Möglicherweise möchten Sie auch versuchen
git diff --Word-diff=plain --Word-diff-regex=. master^ master
und
git diff --Word-diff=porcelain --Word-diff-regex=. master^ master

49
senf78

Python's difflib ist ein Ass, wenn Sie dies programmgesteuert machen möchten. Für die interaktive Verwendung verwende ich den vim - diff-Modus (einfach genug: einfach mit vim mit vimdiff a b aufrufen). Ich benutze auch gelegentlich Beyond Compare , was so ziemlich alles macht, was man von einem Diff-Tool erwarten kann.

Ich sehe kein Befehlszeilentool, das dies sinnvoll tut, aber wie Will bemerkt, könnte der difflib-Beispielcode hilfreich sein.

15
Ned

Sie können den Befehl cmp in Solaris verwenden:

cmp

Vergleichen Sie zwei Dateien, und wenn sie sich unterscheiden, werden das erste Byte und die Zeilennummer dort angegeben, wo sie sich unterscheiden.

13

Sie können verwenden:

diff -u f1 f2 |colordiff |diff-highlight

 screenshot

colordiff ist ein Ubuntu-Paket. Sie können es mit Sudo apt-get install colordiff installieren.

diff-highlight stammt von git (seit Version 2.9). Es befindet sich in /usr/share/doc/git/contrib/diff-highlight/diff-highlight. Sie können es irgendwo in Ihren $PATH legen. Oder holen Sie es sich aus diff-so-fancy project .

12
zhanxw

Python verfügt über eine praktische Bibliothek mit dem Namen difflib, die bei der Beantwortung Ihrer Frage hilfreich sein kann.

Nachfolgend finden Sie zwei Oneliner, die difflib für verschiedene Python-Versionen verwenden.

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()))'

Dies kann als Shell-Alias ​​nützlich sein, der sich mit Ihrem .${Shell_NAME}rc leichter bewegen lässt.

$ 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

Und lesbarere Version zum Einfügen einer eigenständigen Datei.

#!/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)
5
Mr. Deathless

Ich habe auch mein eigenes Skript geschrieben, um dieses Problem mit dem Longest-Common-Untersequenz-Algorithmus zu lösen.

Es wird als solches ausgeführt

JLDiff.py a.txt b.txt out.html

Das Ergebnis ist in HTML mit roter und grüner Farbe. Größere Dateien benötigen exponentiell eine längere Zeit für die Verarbeitung. Dies führt jedoch zu einem echten zeichenweisen Vergleich, ohne zuerst Zeile für Zeile geprüft zu werden.

3
Joshua
cmp -l file1 file2 | wc

Hat gut für mich gearbeitet. Die ganz linke Zahl des Ergebnisses gibt die Anzahl der Zeichen an, die sich unterscheiden.

3
Chris Prince

Farbig, Zeichenebenediff ouput

Was Sie mit dem folgenden Skript und diff-highlight (was Teil von git ist) machen können:

 Coloured diff screenshot

#!/bin/sh -eu

# Use diff-highlight to show Word-level differences

diff -U3 --minimal "[email protected]" |
  sed 's/^-/\x1b[1;31m-/;s/^+/\x1b[1;32m+/;s/^@/\x1b[1;[email protected]/;s/$/\x1b[0m/' |
  diff-highlight

(Dank an @ retraciles Antwort für die sed-Hervorhebung)

3
Tom Hale

Pythons difflib kann dies tun.

Die Dokumentation enthält ein Beispiel Befehlszeilenprogramm für Sie.

Das genaue Format ist nicht das von Ihnen angegebene, aber es wäre einfach, entweder die Ausgabe im Ndiff-Stil zu parsen oder das Beispielprogramm zu ändern, um Ihre Notation zu erzeugen.

2
Will

Hier ist ein Online-Textvergleichstool: http://text-compare.com/

Es kann jedes einzelne Zeichen hervorheben, das anders ist, und den Rest vergleichen.

2
gm2008

Ich denke, die einfachere Lösung ist immer eine gute Lösung ... In meinem Fall hilft mir der Code unten. Ich hoffe, dass es hilft.

#!/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]

Sie können zwei Dateien mit der folgenden Syntax an Ihrem bevorzugten Terminal vergleichen:

$ ./diff.py fileNumber1 fileNumber2
1
Miere

Die meisten dieser Antworten erwähnen die Verwendung von diff-highlight , eines Perl-Moduls. Aber ich wollte nicht herausfinden, wie man ein Perl-Modul installiert. Also habe ich ein paar kleinere Änderungen vorgenommen, um ein eigenständiges Perl-Skript zu sein.

Sie können es installieren mit:

▶ curl -o /usr/local/bin/DiffHighlight.pl \
   https://raw.githubusercontent.com/alexharv074/scripts/master/DiffHighlight.pl

Und die Verwendung (wenn Sie die Ubuntu colordiff in der Antwort von zhanxw erwähnt haben):

▶ diff -u f1 f2 | colordiff | DiffHighlight.pl

Und die Verwendung (wenn nicht):

▶ diff -u f1 f2 | DiffHighlight.pl
0
Alex Harvey

Wenn Sie Ihre Dateien in Git behalten, können Sie mit dem diff-highlight-Skript zwischen den Versionen unterscheiden, wobei unterschiedliche Zeilen mit hervorgehobenen Unterschieden angezeigt werden. 

Leider funktioniert es nur, wenn die Anzahl der entfernten Zeilen mit der Anzahl der hinzugefügten Zeilen übereinstimmt. Wenn die Zeilen nicht übereinstimmen, gibt es einen Stubcode, der vermutlich in Zukunft behoben werden könnte.

0
naught101

Keine vollständige Antwort, aber wenn die Ausgabe von cmp -l nicht klar genug ist, können Sie Folgendes verwenden:

sed 's/\(.\)/\1\n/g' file1 > file1.vertical
sed 's/\(.\)/\1\n/g' file2 > file2.vertical
diff file1.vertical file2.vertical
0