【问题标题】:How to colorize diff on the command line如何在命令行上为差异着色
【发布时间】:2012-02-06 16:55:56
【问题描述】:

当我有差异时,我怎样才能对其进行着色以使其看起来不错?

我希望它用于命令行,所以请不要使用 GUI 解决方案。

【问题讨论】:

标签: unix command-line colors diff


【解决方案1】:

diff 的手册页没有建议从其内部进行着色的解决方案。请考虑使用colordiff。它是 diff 的包装器,产生与 diff 相同的输出,只是它使用彩色语法突出显示来增加输出以提高可读性:

diff old new | colordiff

或者只是:

colordiff old new

安装:

  • Ubuntu/Debian:sudo apt-get install colordiff
  • OS X:brew install colordiffport install colordiff

【讨论】:

  • 刚刚发现自己:-)。可以使用less -R 将其通过管道传输到less,它可以正确显示颜色的转义序列。
  • 可以只使用语法:colordiff file1 file2
  • 唉,它不适用于并排输出(启用-y 选项) ☹ 下面的vimdiff 建议可能是更好的方法
  • colordiff 适用于svn diff | colordiff(即在您只有差异的情况下,而不是被差异的​​两个文件)。
  • 作为@Hi-Angel 评论的更新:colordiff 已更新,现在包括并排 (-y) 支持。
【解决方案2】:

使用Vim:

diff /path/to/a /path/to/b | vim -R -

或者更好的是,VimDiff(或vim -d,打字更短)将并排显示两个、三个或四个文件之间的差异。

示例:

vim -d /path/to/[ab]

vimdiff file1 file2 file3 file4

【讨论】:

  • @Jichao:我更喜欢学习命令而不是别名。这样我就可以在任何地方使用它们,即使我的点文件不可用。
  • @AquariusPower: ctrl-cctrl-x 在 Vim 中有其他用途。 ctrl-q 被许多终端捕获。请参阅 Writing and quitting 以找到最适合您需求的方式。
  • vimdiff 不会处理目录diffs。或者,您可以将 diff 保存到文件中,然后使用 vim 打开它。这样你就可以让vim 使用内置的语法高亮工具对其进行着色。
  • 首先,这是什么外壳? zsh?我不认识=(...) 构造。其次,我想到了diff -ur a b
【解决方案3】:

我使用grc(通用着色器),它允许您为包括diff在内的许多命令的输出着色。

它是一个 Python 脚本,可以包裹任何命令。因此,您可以调用grc diff file1 file2 来查看彩色输出,而不是调用diff file1 file2。我已将 diff 别名为 grc diff 以使其更容易。

【讨论】:

  • 由于fork() 调用,不能在带有 mingw/cygwin 的 Windows 上工作,但可能适用于 WSL。
【解决方案4】:

对于那些由于某些超出您直接控制的疯狂限制而无法选择 yum install colordiffapt-get install colordiff 的情况,或者您只是感觉很疯狂,您可以重新发明带有一行 sed 的轮子:

sed 's/^-/\x1b[41m-/;s/^+/\x1b[42m+/;s/^@/\x1b[34m@/;s/$/\x1b[0m/'

将其放入 shell 脚本并通过管道输出 unified diff

它将大块标记变为蓝色,并分别在绿色和红色背景中突出显示新/旧文件名和添加/删除的行。1并且它将使尾随空格2更改比 colordiff 更明显。


1 顺便提一下,高亮文件名与修改行相同的原因是为了正确区分文件名和修改行需要正确解析 diff 格式,这不是要解决的问题用正则表达式。在视觉上突出它们相同的作品“足够好”并使问题变得微不足道。也就是说,有some interesting subtleties

2 但不是尾随制表符。显然标签没有设置它们的背景,至少在我的xterm 中。不过,它确实使制表符与空格的变化有点突出。

【讨论】:

  • @Matt:这是针对 Mac 的暴力破解方法:sed "s/^-/`echo -e \"\x1b\"`[41m-/;s/^+/`echo -e \"\x1b\"`[42m+/;s/^@/`echo -e \"\x1b\"`[34m@/;s/$/`echo -e \"\x1b\"`[0m/"(尽管我希望有更好的方法)。
  • 嗯,它有点工作...给每个块之间的 3 破折号一个粉红色的背景。
  • 老兄,这太棒了!好样的!这是一些不错的 sed 魔法。
  • 将这种令人敬畏的特性称为 colorize-diff-u。谢谢。
  • sed 's/^-/\x1b[31m-/;s/^+/\x1b[32m+/;s/^@/\x1b[34m@/;s/$/\ x1b[0m/' 看起来也很棒
【解决方案5】:

您可以更改Subversion 配置以使用colordiff:

~/.subversion/config.diff

 ### Set diff-cmd to the absolute path of your 'diff' program.
 ###   This will override the compile-time default, which is to use
 ###   Subversion's internal diff implementation.
-# diff-cmd = diff_program (diff, gdiff, etc.)
+diff-cmd = colordiff

通过:https://gist.github.com/westonruter/846524

【讨论】:

  • svn: 无法启动进程 'colordiff': 资源暂时不可用
  • 你安装了 colordiff 吗?
  • 是的,我也尝试硬编码路径(在 cygwin 中运行)
【解决方案6】:

实际上似乎还有另一种选择(我最近才注意到,当遇到上述问题时):

git diff --no-index <file1> <file2>
# output to console instead of opening a pager
git --no-pager diff --no-index <file1> <file2>

如果您有 Git(您可能已经在使用),那么您将能够使用它进行比较,即使文件本身不受版本控制。如果默认情况下未为您启用,那么在此处启用颜色支持似乎比前面提到的一些解决方法要容易得多。

【讨论】:

  • 这很简洁,但遗憾的是当输入是管道时这不起作用。例如,通过git diff &lt;(xxd file1) &lt;(xxd filed) 比较二进制文件不起作用。
  • 奇怪的是,根据git help diff,至少有一个文件必须在“当前存储库之外”。因此,如果您的 git diff 为空,请尝试cd
  • 启用 git diff 的颜色:git config color.diff auto
  • 如果两个文件都在当前存储库中,请使用git diff --no-index 比较两个文件。
  • 我是git diff --word-diff --patience的粉丝
【解决方案7】:

彩色,字级 diff 输出

您可以使用以下脚本和diff-highlight

#!/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 answer 突出显示sed

【讨论】:

  • 如何在 GVim 中使用这个输出?
  • 对于vim,使用插件,例如diffchar
  • 这个答案更值得称赞!它使用您可能已经拥有的工具链,并且效果非常好(适用于 git log、git show 和 git diff!
【解决方案8】:

由于wdiff 接受指定插入和删除开头和结尾的字符串的参数,您可以使用ANSI color sequences 作为这些字符串:

wdiff -n -w $'\033[30;41m' -x $'\033[0m' -y $'\033[30;42m' -z $'\033[0m' file1 file2

例如,这是比较两个 CSV 文件的输出:

示例来自 2.2 Actual examples of wdiff usage

【讨论】:

  • colordiff 现在 (1.0.16) 理解 wdiff,因此您也可以直接使用管道:wdiff -n f1 f2 | colordiffwdiff 应该合并到 diffutils...
【解决方案9】:

diff --color 选项(在 2016 年 8 月 8 日添加到 GNU diffutils 3.4)

这是大多数发行版上默认的 diff 实现,很快就会得到它。

Ubuntu 18.04(仿生海狸)拥有diffutils 3.6,因此拥有它。

在 3.5 上看起来像这样:

测试:

diff --color -u \
  <(seq 6 | sed 's/$/ a/') \
  <(seq 8 | grep -Ev '^(2|3)$' | sed 's/$/ a/')

显然在提交 c0fa19fe92da71404f809aafb5f51cfd99b1bee2(2015 年 3 月)中添加。

词级差异

喜欢diff-highlight。貌似不可能,但是有一个功能请求:https://lists.gnu.org/archive/html/diffutils-devel/2017-01/msg00001.html

相关问题:

ydiff 会这样做。见下文。

ydiff并排字级差异

https://github.com/ymattw/ydiff

这是涅槃吗?

python3 -m pip install --user ydiff
diff -u a b | ydiff -s

结果:

如果行太窄(默认为 80 列),请使用以下内容适应屏幕:

diff -u a b | ydiff -w 0 -s

测试文件内容:

一个

1
2
3
4
5 the original line the original line the original line the original line
6
7
8
9
10
11
12
13
14
15 the original line the original line the original line the original line
16
17
18
19
20

b

1
2
3
4
5 the original line the original line the original line the original line
6
7
8
9
10
11
12
13
14
15 the original line the original line the original line the original line
16
17
18
19
20

ydiff Git 集成

ydiff 与 Git 集成,无需任何配置。

从 Git 存储库中,而不是 git diff,您可以这样做:

ydiff -s

而不是git log:

ydiff -ls

另请参阅:How can I get a side-by-side diff when I do "git diff"?

Ubuntu 16.04 (Xenial Xerus)、Git 2.18.0 和 ydiff 1.1 上测试。

【讨论】:

  • Here 是文档。
  • 在该邮件列表线程中:There is no word-highlighting, yet - 有任何更新吗?这就是我提出这个问题的原因(我想要grep --color-like diff 输出)。
  • @i336_ 很遗憾没有更新,如果我有任何更新,我会更新问题。如果您发现任何东西,请联系我。
  • 顺便说一下git diff --color 也可以。在 ssh 上工作时很有用。
  • 差异太大?使用diff --color=always | less -R
【解决方案10】:

我建议你试试diff-so-fancy。我在工作期间使用它,它现在看起来确实很棒。它包含许多选项,并且可以很容易地以您想要的方式配置差异。

您可以通过以下方式安装它:

sudo npm install -g diff-so-fancy

或在 Mac 上:

brew install diff-so-fancy

之后,您可以像这样突出显示您的差异:

diff -u file1 file2 | diff-so-fancy

【讨论】:

    【解决方案11】:

    这是另一个解决方案,它调用 sed 来插入适当的 ANSI 转义序列以分别以红色、绿色和青色显示 +-@ 行。

    diff -u old new | sed "s/^-/$(tput setaf 1)&/; s/^+/$(tput setaf 2)&/; s/^@/$(tput setaf 6)&/; s/$/$(tput sgr0)/"
    

    与此问题的其他解决方案不同,此解决方案没有明确说明 ANSI 转义序列。相反,它调用tput setaftput sgr0 命令来生成ANSI 转义序列以分别设置适当的颜色和重置终端属性。

    要查看tput setaf 的每个参数的可用颜色,请使用以下命令:

    for i in {0..255}; do tput setaf $i; printf %4d $i; done; tput sgr0; echo
    

    这是输出的样子:

    这是tput setaftput sgr0 命令生成适当的ANSI 转义序列的证据:

    $ tput setaf 1 | xxd -g1
    00000000: 1b 5b 33 31 6d                                   .[31m
    
    $ tput setaf 2 | xxd -g1
    00000000: 1b 5b 33 32 6d                                   .[32m
    
    $ tput setaf 6 | xxd -g1
    00000000: 1b 5b 33 36 6d                                   .[36m
    
    $ tput sgr0 | xxd -g1
    00000000: 1b 28 42 1b 5b 6d                                .(B.[m
    

    【讨论】:

    • 如果你得到 tput: unkown terminfo capability in 'srg0' 意味着你的操作系统是旧的并且 tput 不能识别 srg0 ,我可以在最后一个 sed 命令中使用 tput setaf 7 来让颜色变回白色
    【解决方案12】:

    在 Ubuntu 上最新版本的 Git 上,您可以启用差异突出显示:

    sudo ln -s /usr/share/doc/git/contrib/diff-highlight/diff-highlight /usr/local/bin
    sudo chmod a+x /usr/share/doc/git/contrib/diff-highlight/diff-highlight
    

    然后将其添加到您的 .gitconfig 文件中:

    [pager]
        log = diff-highlight | less
        show = diff-highlight | less
        diff = diff-highlight | less
    

    脚本可能位于其他发行版的其他位置。您可以使用locate diff-highlight 查找位置。

    【讨论】:

      【解决方案13】:

      使用bat 命令:

      diff file1 file2 | bat -l diff
      

      【讨论】:

      • bat 应该做什么?你能详细说明吗?请通过editing (changing) your answer 回复,而不是在 cmets 中(without "Edit:"、"Update:" 或类似的 - 答案应该看起来像是今天写的)。
      【解决方案14】:

      字符级颜色差异: 安装ccdiff

      ccdiff -r /usr/share/dict/words /tmp/new-dict
      

      【讨论】:

        【解决方案15】:

        对我来说,我找到了一些解决方案:it is a working solution

        @echo off
        Title a game for YouTube
        explorer "https://thepythoncoding.blogspot.com/2020/11/how-to-echo-with-different-colors-in.html"
        SETLOCAL EnableDelayedExpansion
        for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
          set "DEL=%%a"
        )
        echo say the name of the colors, don't read
        
        call :ColorText 0a "blue"
        call :ColorText 0C "green"
        call :ColorText 0b "red"
        echo(
        call :ColorText 19 "yellow"
        call :ColorText 2F "black"
        call :ColorText 4e "white"
        
        goto :Beginoffile
        
        :ColorText
        echo off
        <nul set /p ".=%DEL%" > "%~2"
        findstr /v /a:%1 /R "^$" "%~2" nul
        del "%~2" > nul 2>&1
        goto :eof
        
        :Beginoffile
        

        【讨论】:

        • 虽然 Unix 的标记发生在 6 年后,但 Windows 的这个答案是在 2 年后出现的。
        【解决方案16】:

        我最喜欢的选择是vdiff &lt;file1&gt; &lt;file2&gt; 函数(我忘了从哪里得到它)。

        它会在Vim并排打开两个窗口,看清楚两个文件的区别。

        vdiff () {
            if [ "${#}" -ne 2 ] ; then
                echo "vdiff requires two arguments"
                echo "  comparing dirs:  vdiff dir_a dir_b"
                echo "  comparing files: vdiff file_a file_b"
                return 1
            fi
        
            local left="${1}"
            local right="${2}"
        
            if [ -d "${left}" ] && [ -d "${right}" ]; then
                vim +"DirDiff ${left} ${right}"
            else
                vim -d "${left}" "${right}"
            fi
        }
        

        将此脚本放在您的 (.alias) 或 (.zshrc) 中,然后使用 vdiff .

        示例

        结果是:

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-11-28
          • 2012-06-13
          • 2011-10-28
          • 2019-11-27
          • 1970-01-01
          • 2023-02-01
          • 1970-01-01
          相关资源
          最近更新 更多