web-dev-qa-db-ja.com

'diff'(またはその他)を使用して、テキストファイル間の文字レベルの差分を取得する

「diff」を使用して、行の違いと文字の違いの両方を取得したいと思います。たとえば、次のことを考慮してください。

ファイル1

abcde
abc
abcccd

ファイル2

abcde
ab
abccc

diff -uを使用すると、

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

ただし、これらの行に変更があったことのみが表示されます。私が見たいのは次のようなものです:

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

あなたは私のドリフトを取得します。

これで、特定の行の違いをマーク/チェックするために 他のエンジン を使用できることがわかりました。しかし、私はむしろ、すべてを実行する1つのツールを使用します。

74
VitalyB

GitにはWord diffがあり、すべての文字を単語として定義すると、事実上文字diffが得られます。ただし、改行の変更は無視されます。

例:

次のようなリポジトリを作成します。

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

今、git diff --Word-diff=color --Word-diff-regex=. master^ masterそして、あなたは得るでしょう:

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

追加と削除の両方が文字レベルでどのように認識されるか、改行の追加と削除は無視されることに注意してください。

あなたも試してみたいかもしれません
git diff --Word-diff=plain --Word-diff-regex=. master^ master
そして
git diff --Word-diff=porcelain --Word-diff-regex=. master^ master

55
senf78

次を使用できます。

diff -u f1 f2 |colordiff |diff-highlight

screenshot

colordiffはUbuntuパッケージです。 Sudo apt-get install colordiffを使用してインストールできます。

diff-highlightはgitからのものです(バージョン2.9以降)。 /usr/share/doc/git/contrib/diff-highlight/diff-highlightにあります。 $PATHのどこかに置くことができます。

22
zhanxw

Solarisでcmpコマンドを使用できます。

cmp

2つのファイルを比較し、それらが異なる場合は、最初のバイトと行番号に違いを伝えます。

17

プログラムでこれを実行したい場合、Pythonの difflib はエースです。インタラクティブに使用するには、 vim's diffモードを使用します(使用するのに十分簡単:vimdiff a bでvimを呼び出すだけです)。また、ときどき Beyond Compare を使用します。これは、diffツールから期待できるほとんどすべてのことを行います。

これを便利に行うコマンドラインツールは見当たりませんが、Willが述べているように、difflibのサンプルコードが役立つかもしれません。

15
Ned

Pythonにはdifflibという便利なライブラリがあり、質問に答えるのに役立ちます。

以下は、異なるpythonバージョンにdifflibを使用する2つのonelinersです。

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

これらは、シェルエイリアスとして便利な場合があります。これは、.${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

そして、より読みやすいバージョンをスタンドアロンファイルに配置します。

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

また、 自分のスクリプト を書いて、 最長共通サブシーケンスアルゴリズムを使用してこの問題を解決しました。

そのように実行されます

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

結果は、赤と緑の色が付いたhtmlになります。大きなファイルは処理に指数関数的に長い時間がかかりますが、これは最初に行ごとにチェックすることなく、文字ごとに真の文字を実行します。

5
Joshua
cmp -l file1 file2 | wc

私にとってはうまくいきました。結果の左端の数字は、異なる文字の数を示します。

5
Chris Prince

色付き、文字レベルdiff ouput

以下は、以下のスクリプトと diff-highlight (gitの一部)でできることです:

Coloured diff screenshot

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

@ retracile's answersed強調表示に対するクレジット)

4
Tom Hale

Pythonのdifflibはこれを行うことができます。

ドキュメントには、例 コマンドラインプログラム が含まれています。

正確な形式は指定したとおりではありませんが、ndiffスタイルの出力を解析するか、サンプルプログラムを変更して表記を生成するのは簡単です。

3
Will

オンラインのテキスト比較ツールを次に示します。 http://text-compare.com/

異なるすべての文字を強調表示し、残りを比較し続けることができます。

2
gm2008

単純なソリューションは常に良いソリューションだと思います。私の場合、以下のコードは非常に役立ちます。それが他の誰にも役立つことを願っています。

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

お気に入りの端末で、次の構文を使用して2つのファイルを比較できます。

$ ./diff.py fileNumber1 fileNumber2
1
Miere

これらの回答のほとんどは、Perlモジュールである diff-highlight の使用に言及しています。しかし、Perlモジュールのインストール方法を理解したくありませんでした。そのため、自己完結型のPerlスクリプトになるように、いくつかの小さな変更を加えました。

以下を使用してインストールできます。

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

使用法(zhanxwの回答で言及されているUbuntu colordiffがある場合):

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

そして、使用法(そうでない場合):

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

ファイルをGitに保持する場合、 diff-highlight script を使用してバージョン間で差分をとることができます。これにより、異なる行が表示され、違いが強調表示されます。

残念ながら、削除された行の数が追加された行の数と一致する場合にのみ機能します。行が一致しない場合のスタブコードがあるため、おそらくこれは将来修正される可能性があります。

0
naught101

完全な答えではありませんが、cmp -lの出力は十分に明確ではありません。次を使用できます。

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