Linux上两个文件之间的空格差异


15

我有两个文件,当与diff比较时,它们显示每一行都已更改。当我将它们与diff -w(忽略空格)进行比较时,它显示了我期望的一些最小变化。

显然,每个文件中的空格之间存在一些差异,但是我不知道它们是什么或如何找到它们。我已经尝试编辑文件以确保空格实际上是空格字符(而不是制表符),但是不确定还有其他操作。

我用vim :set list on来确认行尾没有尾随空格。

我也相信每个文件都有Linux行终止符,因为vim没有^M在行末显示。


1
您是否检查了尾随空格(在行尾)?这样的空间将被检测到,diff但是许多编辑器默认情况下不会使该空间可见。
John1024

好建议。我在vim上使用了“:set list on”,这在行尾显示了“ $”,并且没有尾随空格。我将更新我的问题
Romski

如果您是vim用户,那么您是否尝试过使用vimdiff file1 file2以查看差异?
John1024

@ John1024我不知道vimdiff,但是看起来很有希望。将其添加为答案,我会接受
Romski 2015年

1
Vim仅在错误地检测到Unix行尾但文件实际上具有DOS行尾时才显示^ M。通常,如果您在单个文件中混合了行尾,例如,应用补丁而行尾与原始文件不同的补丁,就会发生这种情况。当vim检测到DOS行正确结束时,它不会显示^ M。
Lie Ryan

Answers:


7

对于vim用户而言,有一个方便的实用工具可以显示文件之间的确切差异:

vimdiff file1 file2

这会将每个文件并排放置在Windows中,并以高亮显示差异。

进入时的一些有用命令 vimdiff

在中时vimdiff,一些有用的命令是:

  • ]c:跳到下一个更改

  • [c:跳至上一个更改

  • ctrl-W ctrl-W:切换到其他窗口

  • zo:开折

  • zc:褶皱

下面是一个例子vimdiff中的xterm一个进行比较两个版本cups的配置文件:

在此处输入图片说明

您会看到相同行的长段已折叠。可以使用打开它们zo

颜色方案将根据您的选项设置而有所不同。在上面的示例中,当一行出现在一个文件中而不出现在另一个文件中时,该行将被赋予深蓝色背景。在另一个文件中,缺失的行用虚线表示。当两个文件中都出现一行但有一些差异时,行的未更改部分将具有粉红色背景,而已更改的部分将具有红色背景。


14

在FreeBSD或大多数Linux系统上,您可以通过管道传递diff的输出cat -v -e -t以显示空格差异。

diff file1 file2 | cat -vet

选项卡将显示为^I$每行的末尾将显示一个a ,以便您可以看到尾随空白,非打印字符将显示为^XM-X

如果您具有GNU coreutils(在大多数非busybox Linux发行版中可用),则可以简化为

diff file1 file2 | cat -A

在busybox系统上,使用catv -vet


2

是在Windows机器上编辑的文件之一吗?

Windows上的标准线路终端是CRLF,而在Linux上则是LF(在Mac上曾经是CR,但是我怀疑自OS X以来这种情况已经改变了)。

试一试wc -l文件,看看有多少行,然后查看大小差异是否与行数相同(一个文件中的最后一行可能不会终止)。


感谢您的快速答复。行数计算表明一个文件还有5行(我希望这样做,因为我已经进行了编辑)。我从Linux机器上获得一个文件,另一个文件从代码存储库中签出到Linux。我相信在vim中使用Windows终止符查看文件时,最后一个字符将显示为^ M,事实并非如此。
罗姆斯基

3
vim实际上足够聪明,可以自动检测线路终止,有关详细信息,请参见stackoverflow.com/questions/3852868
fencepost

我没有意识到!我会重新检查
Romski

2

od可能会有所帮助。八进制转储命令可以以十六进制显示内容。这可以帮助您查看文件中有哪些字节,包括空字节或意外的空格。可能的常见原因可能是LF vs CRLF,制表符vs空格或ASCII vs Unicode(通常在每个通常可见的字节之前只有一个空字节)。 od -x filename应该揭示任何一种模式。如果您想以更精细的方式查看文件,则任何“十六进制编辑器”都可以很好地实现。令人高兴的odcut,它与命令一样,已内置在许多Unix系统中。因此,通常不需要单独安装。

如果您需要文件更加相似,tr可以进行一些更改,然后sed进行更多更改。我可能首先ls -l看哪个文件更大,然后查看字节以查看需要更改的内容,然后更改其中一个文件,使它们看起来更相似。


1

要找出真正的空格和制表符在哪里,您可以使用sed以下示例替换它们:

$ cat file
  line 1
  line 2
    line 6
        line 7
$ sed 's/ /-/g; s/\t/<tab>/g' file
--line-1
--line-2
<tab>line-6
<tab><tab>line-7

现在比较两个文件。


更好的是,您可以在diff输出上运行该过滤器。或者,您可以在中使用现成的过滤器cat,如superuser.com/a/913368/37154
clacke 2015年

0

以下内容是从上面由Romski编写的“问题”部分复制而来的。

从工具的角度来看,两者vimdiffdiff file1 file2 | cat -A都非常有用。

最后,我发现了另一个问题。我的某些文件是使用UTF-8 BOM编码的。使用突出显示了这一点diff file1 file2 | cat -A。这表现M-oM-;M-?在受影响文件的开头:

$ diff file1 file2 | cat -A
< package com.mycompany;$
---$
> M-oM-;M-?package com.mycompany;$

尽管存在许多问题,但我在下面列出了一些需要清理文件的命令:

# recursively remove UTF8 BOM
find . -type f -exec sed -i -e '1s/^\xEF\xBB\xBF//' {} \;

# recursively replace CRLF with LF
find . -type f -print0 | xargs -0 dos2unix
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.