我有一些SQL转储,我正在看它们之间的差异。 diff显然可以向我显示两行之间的差异,但是我很努力地试图找出长逗号分隔值列表中的哪些值实际上是导致行不同的值。

我可以使用什么工具指出某些文件中两行之间的确切字符差异?

评论

superuser.com/questions/496415/…| stackoverflow.com/questions/1342256/…

#1 楼

有wdiff,即diff。

评论


彩色wdiff:wdiff -w“ $(tput粗体; tput setaf 1)” -x“ $(tput sgr0)” -y“ $(tput粗体; tput setaf 2)” -z“ $(tput sgr0)” file1 file2

–l0b0
2011年4月12日上午11:21

对于颜色,请安装colordiff,然后执行以下操作:wdiff a b |色差

– philfreo
2013年9月28日在3:36



在显示与基于行的文件之间的行内差异时,Meld实际上非常慢(几分钟)。

– Dan Dascalescu
17年6月28日在22:02

还有一个dwdiff工具,它与wdiff大部分兼容,但也支持彩色输出以及其他一些功能。而且它在某些Linux发行版(例如Arch)中更可用。

– MarSoft
17年8月31日在0:13

wdiff -n a b | colordiff,建议男人colordiff。

– Camille Goudeseune
18年5月4日在17:50

#2 楼

另一种使用git-diff的方法:

git diff -U0 --word-diff --no-index -- foo bar | grep -v ^@@


grep -v,如果对差异的位置不感兴趣。

评论


这正是我要模仿的行为-没意识到我可以在没有索引其中一个文件的情况下使用git-diff。

–旋转
17-10-10在0:27

--word-diff是这里的关键选项。谢谢!

–user2707671
18年8月17日在13:04

--no-index仅在您位于git工作目录中并且foo和bar都必需时才是必需的。

– xn。
19年2月12日在21:00

#3 楼

我已经为此使用vimdiff

这是一个截图(不是我的),显示了很小的一两个字符差异,非常明显。也是一个快速的教程。

评论


在我的情况下,无法发现差异,因此在gvim -d f1 f2中打开了文件,特定的长行都被突出显示为不同,但是实际差异以红色突出

– zzapper
2015年12月9日在16:54



我一直在使用vim,但对vimdiff却一无所知!

– mitchus
17年4月3日在16:02

还有用于字符级差异的diffchar.vim。

–user37050
17年11月16日23:52

尽管我喜欢vim和vimdiff,但vimdiff的用于突出显示行中差异的算法非常基础。似乎只是去掉了通用的前缀和后缀,并强调了两者之间的所有区别。如果所有更改的字符都组合在一起,则此方法有效,但是如果将它们分散开,则效果不佳。换行文字也很糟糕。

–劳伦斯·贡萨尔维斯(Laurence Gonsalves)
17年12月21日在20:49

对于像OP中的长行,vimdiff -c'set wrap'-c'wincmd w'-c'set wrap'a b,建议stackoverflow.com/a/45333535/2097284。

– Camille Goudeseune
18年5月4日在17:54

#4 楼

这是“咬狗的狗毛。”方法。使用它带您进一步了解...

这里是使用采样线对的输出... diff表示TAB >
这里是脚本。.您只需要以某种方式找出线对。.(今天之前,我仅使用diff一次(两次?),所以我不知道它的很多选项和排序方式一天下来,这个脚本的选项对我来说足够了:) ..我认为它必须足够简单,但是我要喝咖啡休息一下.... />

#5 楼

wdiff实际上是一种逐字比较文件的非常古老的方法。它通过重新格式化文件来工作,然后使用diff查找差异并将其再次传递回去。我本人建议添加上下文,以使每个单词都被其他“上下文”单词包围,而不是逐单词进行比较。这使得diff可以更好地在文件中的普通段落上进行自身同步,尤其是当文件之间的差异很大,只有几个普通字块时。例如,当比较文本以进行gi窃或重复使用时。

dwdiff后来从wdiff创建。但是dwdiffdwfilter中使用该文本重新格式化功能效果良好。这是一个了不起的进步–这意味着您可以重新格式化一个文本以匹配另一个文本,然后使用任何逐行图形化差异显示工具比较它们。例如,将其与“ diffuse”图形差异一起使用。 file1是未修改的,因此您可以在file2中直接将单词差异编辑并合并到其中。如果要编辑diffuse,可以添加file2以撤消重新格式化该文件的操作。试试看,您会发现它非常强大!

我对图形差异(如上所示)的偏爱是diffuse,因为它感觉更干净,更有用。它也是一个独立的python程序,这意味着它很容易安装并分发到其他UNIX系统。 。这些包括file1-r

#6 楼

我以@ Peter.O的解决方案为基础重写了它,进行了许多更改。显示差异。
它不会写入任何临时文件,而会将所有内容都管道化。
您可以提供两个文件名,并将比较每个文件中的相应行。 ./hairOfTheDiff.sh file1.txt file2.txt

否则,如果您使用原始格式(一个文件,第二行需要与之前的第二行进行比较),现在可以简单地将其插入,无需读取任何文件。看一下源代码中的demo;使用paste和多个文件描述符可以为花哨的管道打开大门,从而也不需要两个单独输入的文件。第一个表示红色,第二个表示红色。 />
 #!/bin/bash

same='-' #unchanged
up='△' #exists in first line, but not in second 
down='▽' #exists in second line, but not in first
reset=''

reset=$'\e[0m'
same=$reset
up=$reset$'\e[1m\e[7m'
down=$reset$'\e[1m\e[7m\e[31m'

timeout=1


if [[ "" != '' ]]
then
    paste -d'\n' "" "" | "q4312079q"
    exit
fi

function demo {
    "q4312079q" <<EOF
Paris in the spring 
Paris in the the spring
A cat on a hot tin roof.
a cant on a hot in roof
the quikc brown box jupps ober the laze dogs 
The quickbrown fox jumps over the lazy dogs
EOF
}

# Change \x20 to \x02 to simplify parsing diff's output,
#+   then change \x02 back to \x20 for the final output. 
# Change \x09 to \x01 to simplify parsing diff's output, 
#+   then change \x01 into → U+1F143 (Squared Latin Capital Letter T)
function input {
    sed \
        -e "s/\x09/\x01/g" \
        -e "s/\x20/\x02/g" \
        -e "s/\(.\)/\n/g"
}
function output {
    sed -n \
        -e "s/\x01/→/g" \
        -e "s/\x02/ /g" \
        -e "s/^\(.\) *\x3C$/ \x3C  /g" \
        -e "s/\(.\) *\(.\) \(.\)$//p"
}

ifs="$IFS"
IFS=$'\n'
demo=true

while IFS= read -t "$timeout" -r a
do
    demo=false
    IFS= read -t "$timeout" -r b
    if [[ $? -ne 0 ]]
    then
        echo 'No corresponding line to compare with' > /dev/stderr
        exit 1
    fi

    diff --text -yt -W 19  \
        <(echo "$a" | input) \
        <(echo "$b" | input) \
    | \
    output | \
    {
        type=''
        buf=''
        while read -r line
        do
            if [[ "${line:1:1}" != "$type" ]]
            then
                if [[ "$type" = '|' ]]
                then
                    type='>'
                    echo -n "$down$buf"
                    buf=''
                fi

                if [[ "${line:1:1}" != "$type" ]]
                then
                    type="${line:1:1}"

                    echo -n "$type" \
                        | sed \
                            -e "s/[<|]/$up/" \
                            -e "s/>/$down/" \
                            -e "s/ /$same/"
                fi
            fi

            case "$type" in
            '|')
                buf="$buf${line:2:1}"
                echo -n "${line:0:1}"
                ;;
            '>')
                echo -n "${line:2:1}"
                ;;
            *)
                echo -n "${line:0:1}"
                ;;
            esac
        done

        if [[ "$type" = '|' ]]
        then
            echo -n "$down$buf"
        fi
    }

    echo -e "$reset"
done

IFS="$ifs"

if $demo
then
    demo
fi
 


#7 楼

这是一个简单的单行代码:

diff -y <(cat a.txt | sed -e 's/,/\n/g') <(cat b.txt | sed -e 's/,/\n/g')

这个想法是使用sed用换行符替换逗号(或希望使用的任何定界符)。然后,diff会照顾其余的人。

#8 楼


xxdiff:另一个工具是xxdiff(GUI),首先必须安装它。
电子表格:对于数据库数据,可以轻松制作来自.csv的电子表格,并插入公式(A7==K7) ? "" : "diff"或类似内容并复制粘贴。

评论


xxdiff看起来像80年代。融合看起来好多了,但是对于类似CSV的文件来说却非常慢。我发现Diffuse是最快的Linux diff工具。

– Dan Dascalescu
17年6月28日在22:01

@DanDascalescu:完成工作的工具无论看起来有多老,看起来总是很好。我偶尔用过的另一个tkdiff是用来安装长列数据来测试它的,但我偶尔使用它。

–用户未知
17年6月29日在3:08

xxdiff是否显示移动的行?还是只是在一个文件中显示缺失行,而在另一个文件中显示缺失行? (我尝试构建xxdiff,但qmake失败了,我发现他们不必费心发布Debian软件包)。

– Dan Dascalescu
17年6月29日在3:25

@DanDascalescu:今天,我只安装了tkdiff。

–用户未知
17年6月30日在0:37

#9 楼

在命令行上,我将确保在比较文件之前添加明智的换行符。您可以使用sed,awk,perl或其他任何东西来以某种系统的方式添加换行符-请确保不要添加过多的换行符。突出显示单词差异。如果没有太多差异并且差异很简单,那么vim很好。

评论


尽管这并不是对问题的真正答案,但该技术对于了解长行中的细微差异非常有效。

– jk-恢复莫妮卡
15年2月4日在19:05

#10 楼

如果我正确地阅读了您的问题,则可以使用diff -y进行这种处理。

评论


这不会突出显示行内的差异。如果您的路线很长,那么看到差异就很痛苦。 wdiff,git diff --word-diff,vimgit,meld,kbdiff3,tkdiff都可以执行此操作。

–user2707671
18年8月17日在13:07

#11 楼

我遇到了同样的问题,并使用PHP Fine Diff(一个允许您指定粒度的在线工具)解决了该问题。我知道从技术上讲它不是* nix工具,但我并不是真的想下载一个程序来进行一次字符级差异比较。

评论


有些用户无法将敏感文件或大文件上传到随机的在线工具。有很多工具可以显示行级差异,而​​又不会损害您的隐私。

– Dan Dascalescu
17年6月28日在22:01

是的,有。但是对于不包含敏感信息的差异,联机工具可能是一个很好的解决方案。

– pillravi
17年7月3日在14:01

在线差异工具也不支持命令行集成。您不能从版本控制流程中使用它们。使用它们也很麻烦(选择文件1,选择文件2,上传),并且无法合并。

– Dan Dascalescu
17年7月4日在18:41

#12 楼

GNU Emacs具有非常好的“ ediff”模式。我使用它并经常按ab
高级用户会更加喜欢,例如:https://emacs.stackexchange.com/questions/16469/how-to-merge-git-conflicts-in-emacs

它具有许多强大的功能。扩展的帮助菜单:

我强烈建议将菜单中显示的功能提交到内存中,以便在有用时使用它们。 (哇,我没看菜单太久了,它具有我忘了的功能。)
每个* nix平台都可以使用Emacs。而且它是开源的。
我经常使用ediff,以至于键入M-x ediff花费的时间太长,所以我将其绑定到C-c C-e

评论


惊讶的emacs在10年内没有被提及,但是我看到这个问题引起了很多关注,因此添加了此答案。

–马修·埃尔维(Matthew Elvey)
20-10-7在18:47

+1就个人而言,尽管我同时依赖于这两种工具,但我发现ediff在词粒度方面要优于vimdiff。

–crw
20-11-12在22:43



#13 楼

kdiff3成为Linux上的标准GUI差异查看器。它类似于xxdiff,但我认为kdiff3更好。它做得很好,包括您要求显示“某些文件中两行之间的确切字符差异”。

评论


KDiff3突出显示CSV文件中的内联差异的速度非常慢。我不推荐它。

– Dan Dascalescu
17年6月28日在22:00