【问题标题】:how can I diff two sections of the same file?如何区分同一文件的两个部分?
【发布时间】:2023-03-18 19:54:01
【问题描述】:

我有一个包含两个相似但略有不同的部分的源文件。我想将这两个部分合并到一个子程序中,并带有一个处理细微差异的参数,但我需要确保我了解它们,所以我不会错过任何一个。
在这种情况下,我通常做的是将每个部分复制到一个单独的文件中,然后使用 tkdiff 或 vimdiff 来突出显示差异。有什么方法可以跳过中间文件,只区分同一文件的两个部分?

【问题讨论】:

    标签: linux language-agnostic diff


    【解决方案1】:

    Vim 的linediff 插件非常适合我。直观地选择文件的一部分并输入:Linediff。直观地选择其他部分并输入:Linediff。它会将 vim 置于vimdiff 模式,仅显示您之前突出显示的两个部分。输入:LinediffReset 退出 vimdiff 模式。

    更多信息:

    https://unix.stackexchange.com/a/52759/32477

    https://superuser.com/a/414958/199800

    【讨论】:

      【解决方案2】:

      KDiff3 是开源的,可在包括 Win32 和 Linux 在内的多个平台上使用。

      它具有 Gishu 讨论过的关于 Beyond Compare 的“手动对齐”功能(顺便说一下,我没有亲自使用过,但我认识的很多人都认为它是一个很棒的工具)。

      有关更多示例,请参阅this answer

      【讨论】:

        【解决方案3】:

        我使用Beyond Compare
        它允许您在每一侧选择一条线并说“手动对齐”。这对你来说应该很好。

        【讨论】:

        • 谢谢!我通常在 Linux 中工作,但可以使用 Samba 从我的 Windows 机器访问我在 NFS 上的文件。我会试试看。是否有任何 Linux 原生的工具可以做同样的事情?
        • 通过谷歌搜索,似乎 BC v3 可用于 Linux。正如有人发布的“BC 值得为它启动一个 Windows 盒子”:) scootersoftware.com/moreinfo.php?zz=kb_linux
        • 如果部分足够接近,手动对齐效果很好,但我发现有时可能很乏味,要让它不匹配那一行,然后跳过巨大的文本部分来重新对齐文件。但是它不需要明确的文件,您可以复制并粘贴(使用ctrl-shift-v)到一个新的“文本比较”选项卡中。 (BC 是迄今为止我用过的最好的文件区分工具。)
        【解决方案4】:

        我选择将@ordnungswidrig 的答案改写为 bash 函数(我只对单个文件的差异感兴趣,但这可以很容易地更改为处理两个不同的文件...):

        # 查找文件中的差异,给出两个部分的开始行和结束行 功能 diff_sections { 本地 fname=`basename $1`; 本地临时文件=`mktemp -t $fname`; 头 -$3 $1 |尾 +$2 > $tempfile && 头 -$5 $1 |尾 +$4 |差异 -u $tempfile - ; rm $临时文件; }

        你这样调用函数... diff_sections path/to/file 464 483 485 506

        【讨论】:

        • diff -u <(head -$3 $1 | tail -n +$2) <(head -$5 $1 | tail -n +$4)
        【解决方案5】:

        任何可让您手动调整对齐的差异工具都可以完成这项工作。漫反射 (http://diffuse.sourceforge.net/) 是我的最爱,它还可以让您手动调整对齐方式。

        【讨论】:

          【解决方案6】:

          如果您可以使用正则表达式描述要组合的部分的开头和结尾,则可以使用以下内容:

          sh -c 't=`mktemp`; cat "$0" | grep -e "$2" -A10000 | grep -e "$3" -B 10000 > $t; cat "$1" | grep -e "$2" -A10000 | grep -e "$3" -B 10000 | diff -u $t - ; rm $t' firstfile secondfile "section start" "section end"
          

          如果您想按行号描述部分,您可以这样做:

          sh -c 't=`mktemp`; cat "$0" | head -$3 |tail +$2 > $t; cat "$1" | head -$5 | tail +$4 | diff -u $t - ; rm $t' first second 4 10 2 8
          

          4 10 2 8 是第一个文件和第二个文件中要考虑的部分的开始和结束行号。

          您可以将 sn-ps 保存为 shell 脚本或作为别名。

          【讨论】:

          • 第二个不起作用..你不能那样尾随..需要-n
          【解决方案7】:

          Emacs 对此有 ediff-regions-wordwise —— 您可以使用两个缓冲区(或仅一个)并在每个缓冲区中选择一个区域,然后 ediff 将显示该区域以供比较。

          【讨论】:

            猜你喜欢
            • 2022-11-30
            • 1970-01-01
            • 2011-12-29
            • 2021-11-13
            • 1970-01-01
            • 2013-12-10
            • 1970-01-01
            相关资源
            最近更新 更多