【问题标题】:space/tab/newline insensitive comparison空格/制表符/换行不敏感比较
【发布时间】:2012-09-03 22:46:18
【问题描述】:

假设我有这两个文件:

文件 1: 1 2 3 4 5 6 7

文件 2:

1
2
3
4
5
6
7

是否可以使用diff来比较这两个文件,结果是equal?

(如果没有,我应该使用哪些其他工具?)

谢谢

【问题讨论】:

  • 将换行符(或者\s+\r+)转换为空格然后检查?
  • diff -w(与diff --ignore-all-space相同)有帮助吗?

标签: string bash shell comparison diff


【解决方案1】:

如果事实证明数据确实足够简单,不会遇到限制,并且文件之间的唯一区别是第一个用空格分隔,第二个用换行符分隔,您也可以进行进程替换(如建议的那样上面)但用 sed 用换行符替换第一个文件中的空格:

diff <(sed 's/ /\n/g' file1) file2

【讨论】:

    【解决方案2】:

    您可以折叠空格,使file2 看起来像file1,每个数字都在同一行:

    $ cat file1
    1 2 3 4 5 6 7
    $ cat file2
    1
    2
    4
    3
    5
    6
    7
    $ diff <(echo $(< file1)) <(echo $(< file2))
    1c1
    < 1 2 3 4 5 6 7
    ---
    > 1 2 4 3 5 6 7
    

    解释:

    < file             # Equivalent to "cat file", but slightly faster since the shell doesn't
                       #     have to fork a new process.
    
    $(< file)          # Capture the output of the "< file" command. Can also be written
                       #     with backticks, as in `< file`.
    
    echo $(< file)     # Echo each word from the file. This will have the side effect of
                       #     collapsing all of the whitespace.
    
    <(echo $(< file))  # An advanced way of piping the output of one command to another.
                       #     The shell opens an unused file descriptor (say fd 42) and pipes
                       #     the echo command to it. Then it passes the filename /dev/fd/42 to
                       #     diff. The result is that you can pipe two different echo commands
                       #     to diff.
    

    或者,您可能想让file1 看起来像file2,每个数字在不同的行上。这将产生更有用的差异输出。

    $ diff -u <(printf '%s\n' $(< file1)) <(printf '%s\n' $(< file2))
    --- /dev/fd/63  2012-09-10 23:55:30.000000000 -0400
    +++ file2   2012-09-10 23:47:24.000000000 -0400
    @@ -1,7 +1,7 @@
     1
     2
    -3
     4
    +3
     5
     6
     7
    

    这类似于第一个命令,将 echo 更改为 printf '%s\n' 以在每个单词后放置一个换行符。

    注意:如果要比较的文件过长,这两个命令都会失败。这是因为命令行长度的限制。如果发生这种情况,您将需要解决此限制,例如将 echo/printf 的输出存储到临时文件中。

    【讨论】:

    • 归一化为换行符会产生更整洁的差异。 diff &lt;(tr -s ' \t' '\n' &lt;file1) &lt;(tr -s ' \t' '\n' &lt;file2)
    【解决方案3】:

    一些差异有-b(忽略空格)和-w(忽略空格),但由于unix实用程序都是面向行的,我不认为空格会包含\n字符。

    检查您的diff 版本是否没有带有diff --help | less 或man diff 的花哨的gnu 选项。

    上面的格式是否正确,文件 1,数据全部在一行上?您可以强制 file2 与该格式匹配

    awk '{printf"%s ", $0}' file2 
    

    或者如cmets中所说,转换文件1

    awk '{for (i=1;i<=NF;i++) printf("%s\n", $i)}' file1
    

    但我猜你的数据并不是那么简单。当您最没有时间处理它们时,可能会出现行长度限制。

    可能不是你想听到的,diffing 像源代码这样复杂的东西并不是一门精确的科学。因此,如果您仍然需要帮助,请创建一个稍微复杂一点的测试用例并将其添加到您的问题中。

    最后,您需要向我们展示您希望这样一个差异项目的输出是什么样子。现在我看不到任何有意义的方式来显示非平凡案例的这种差异。 IHTH

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多