AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / ubuntu / 问题 / 1073349
Accepted
sancho.s ReinstateMonicaCellio
sancho.s ReinstateMonicaCellio
Asked: 2018-09-09 04:50:05 +0800 CST2018-09-09 04:50:05 +0800 CST 2018-09-09 04:50:05 +0800 CST

比较源代码文件,忽略格式差异(如空格、换行符等)

  • 772

我正在寻找一个可以比较两个 C++ 源代码并找到代码意义差异的应用程序(以比较可能已重新格式化不同的版本)。至少,能够忽略不影响源功能的空格、制表符和换行符的变化的东西(请注意,换行符是否被认为是空格取决于语言,而 C 和 C++ 这样做)。而且,理想情况下,可以准确识别所有对代码有意义的差异。我在 Ubuntu 下。

根据diff --help | grep ignore,我希望diff -bBwZ能合理地完成这项工作(我希望得到一些假阴性,稍后再处理)。然而,事实并非如此。

如果我有以下带有片段的文件

test_diff1.txt

    else if (prop == "P1") { return 0; }

和 test_diff2.txt

    else if (prop == "P1") {
        return 0;
    }

然后

$ diff -bBwZ test_diff1.txt test_diff2.txt
1c1,3
<     else if (prop == "P1") { return 0; }
---
>     else if (prop == "P1") {
>         return 0;
>     }

而不是空的结果。

在两个输入上使用代码格式化程序作为“过滤器”可能会过滤掉这些差异,但随后必须将结果输出绑定回原始输入,以便最终报告差异以保留实际的文本和行号。因此,无需适当的编译器即可实现目标......不过,我不知道是否有可用的东西。

可以达到目标diff吗? 否则,是否有替代方案(最好是命令行)?

diff text-processing
  • 3 3 个回答
  • 1681 Views

3 个回答

  • Voted
  1. Best Answer
    N0rbert
    2018-09-09T07:42:55+08:002018-09-09T07:42:55+08:00

    您可以使用dwdiff. 来自man dwdiff:

    dwdiff- 一个分隔的单词差异程序

    程序非常聪明 - 请参阅dwdiff --help:

    $ dwdiff --help
    Usage: dwdiff [OPTIONS] <OLD FILE> <NEW FILE>
    -h, --help                             Print this help message
    -v, --version                          Print version and copyright information
    -d <delim>, --delimiters=<delim>       Specify delimiters
    -P, --punctuation                      Use punctuation characters as delimiters
    -W <ws>, --white-space=<ws>            Specify whitespace characters
    -u, --diff-input                       Read the input as the output from diff
    -S[<marker>], --paragraph-separator[=<marker>]  Show inserted or deleted blocks
                                   of empty lines, optionally overriding the marker
    -1, --no-deleted                       Do not print deleted words
    -2, --no-inserted                      Do not print inserted words
    -3, --no-common                        Do not print common words
    -L[<width>], --line-numbers[<width>]   Prepend line numbers
    -C<num>, --context=<num>               Show <num> lines of context
    -s, --statistics                       Print statistics when done
    --wdiff-output                         Produce wdiff compatible output
    -i, --ignore-case                      Ignore differences in case
    -I, --ignore-formatting                Ignore formatting differences
    -m <num>, --match-context=<num>        Use <num> words of context for matching
    --aggregate-changes                    Allow close changes to aggregate
    -A <alg>, --algorithm=<alg>            Choose algorithm: best, normal, fast
    -c[<spec>], --color[=<spec>]           Color mode
    -l, --less-mode                        As -p but also overstrike whitespace
    -p, --printer                          Use overstriking and bold text
    -w <string>, --start-delete=<string>   String to mark begin of deleted text
    -x <string>, --stop-delete=<string>    String to mark end of deleted text
    -y <string>, --start-insert=<string>   String to mark begin of inserted text
    -z <string>, --stop-insert=<string>    String to mark end of inserted text
    -R, --repeat-markers                   Repeat markers at newlines
    --profile=<name>                       Use profile <name>
    --no-profile                           Disable profile reading
    

    测试它:

    cat << EOF > test_diff1.txt
        else if (prop == "P1") { return 0; }
    EOF
    
    cat << EOF > test_diff2.txt
        else if (prop == "P1") {
            return 0;
        }
    EOF
    

    然后启动比较:

    $ dwdiff test_diff1.txt test_diff2.txt --statistics
        else if (prop == "P1") {
            return 0;
        }
    old: 9 words  9 100% common  0 0% deleted  0 0% changed
    new: 9 words  9 100% common  0 0% inserted  0 0% changed
    

    请注意100% common以上。

    • 9
  2. Ray
    2018-09-09T07:21:18+08:002018-09-09T07:21:18+08:00

    我怀疑这是 diff 可以做的事情。如果一行内有空间变化,那么它将起作用(或其他类似的程序,如 kompare)。更糟糕的是,您可以执行搜索和替换和折叠制表符等。但是您要求的空格会超出一行...

    您需要一个理解 C++ 语言的程序。请注意,所有语言都是不同的,特别是 Python 使用空格来定义代码块。因此,我怀疑任何通用的类似差异的程序都可以与“任何”(或特定的)编程语言一起使用。

    您可能会考虑使用某种解析器来遍历两个源文件,然后比较该解析器的输出。

    这超出了我的背景,但我建议您研究Lex和Yacc。这些是维基百科页面;你可能想看看这个页面,它给出了一个简明的解释和一个例子。

    • 1
  3. Andrey Starodubtsev
    2019-04-19T09:48:08+08:002019-04-19T09:48:08+08:00

    在类似情况下,当我需要以与git代码格式无关的方式比较两个分支时,我这样做了:

    1. 创建临时分支:

      $ git co feature-a
      $ git co -b 1
      $ git co feature-b
      $ git co -b 2
      
    2. 使用以下格式格式化两个分支clang-format:

      $ git co 1
      $ find . -name '*.cpp' -print0 | parallel -0 -n 1 clang-format -i -style=google
      $ git ci -a -m1 --no-verify
      $ git co 2
      $ find . -name '*.cpp' -print0 | parallel -0 -n 1 clang-format -i -style=google
      $ git ci -a -m2 --no-verify
      
    3. 做了实际比较:

      $ git diff -w -b 1 2
      

      (-w -b允许您忽略空间差异,以防万一)。

    您可能更喜欢uncrustify( clang-format' uncrustifysmod_full_brace_if可用于强制插入/删除单行if主体周围的花括号)。

    parallel此外,如果未安装GNU ,请使用xargs- 它的作用相同,但时间长一点。

    • 0

相关问题

  • 在 Ubuntu 和 Debian 存储库之间区分 deb-src 包的工具

  • 文件和目录比较工具?

  • 带有 diff 的特定单词的 Ingore 行

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何运行 .sh 脚本?

    • 16 个回答
  • Marko Smith

    如何安装 .tar.gz(或 .tar.bz2)文件?

    • 14 个回答
  • Marko Smith

    如何列出所有已安装的软件包

    • 24 个回答
  • Marko Smith

    无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗?

    • 25 个回答
  • Martin Hope
    Flimm 如何在没有 sudo 的情况下使用 docker? 2014-06-07 00:17:43 +0800 CST
  • Martin Hope
    Ivan 如何列出所有已安装的软件包 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    La Ode Adam Saputra 无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗? 2010-11-30 18:12:48 +0800 CST
  • Martin Hope
    David Barry 如何从命令行确定目录(文件夹)的总大小? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher “以下软件包已被保留:”为什么以及如何解决? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford 如何删除 PPA? 2010-07-30 01:09:42 +0800 CST

热门标签

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve