防止差异检查文件末尾的换行符

blu*_*ast 27 diff

我有两棵大树,我想比较一下。树中的某些文件之所以不同,只是因为一个文件末尾有换行符,而另一个文件缺少此换行符。我想忽略这个事实。我试过这样打电话diff

diff --ignore-all-space -r <dir1> <dir2>
Run Code Online (Sandbox Code Playgroud)

这是有效的。我的问题是它还忽略了其他差异(与空间相关),这可能很重要。

总结:我只想忽略 EOF 处的换行符。这可能diff吗?

mic*_*ael 18

您基本上需要比较两个文件,有条件地忽略尾随字节。没有“差异”选项可以做到这一点——但有很多方法可以做到(例如,十六进制差异也会出现在脑海中。)

要使用 'diff',您基本上必须修改文件末尾缺少换行符的文件,然后进行比较。您可以使用修改后的文件创建一个临时目录,或者通过一些脚本编写它可以在内存中完成。(至于哪个是首选取决于偏好,文件大小,文件数量......)

例如,以下将修改文件的内容(用于sed -i就地修改,这只是打印到标准输出),如果缺少换行符,则添加一个换行符(如果已经有换行符,则保持文件不变):

sed -e '$a\'  file1.txt
Run Code Online (Sandbox Code Playgroud)

只是为了查看 'diff' 语法(返回 true 表示它们相同,false 表示不同):

$ diff a/file1.txt   b/file1.txt  \
      && echo '** are same' || echo '** are different'
2c2
< eof
---
> eof
\ No newline at end of file
** are different
Run Code Online (Sandbox Code Playgroud)

验证只有空格不同:

$ diff --ignore-all-space  a/file1.txt   b/file1.txt \
     && echo '** are same' || echo '** are different'
** are same
Run Code Online (Sandbox Code Playgroud)

在 bash 中,我们可以使用 'sed' 来操作传递给 'diff' 的文件内容(原始文件保持不变):

$ diff <(sed -e '$a\' a/file1.txt) <(sed -e '$a\' b/file1.txt) \
     && echo '** are same' || echo '** are different'
** are same
Run Code Online (Sandbox Code Playgroud)

现在您要做的就是模拟diff -r以递归方式比较目录。如果比较目录ab,然后在所有文件a(例如,a/dir1/dir2/file.txt在)导出路径文件b(例如,b/dir1/dir2/file.txt)和比较:

$ for f in $( find a -type f  )
> do
>    diff <(sed -e '$a\' $f) <(sed -e '$a\' b/${f#*/})
> done
Run Code Online (Sandbox Code Playgroud)

稍微详细一点的版本:

$ for f in $( find a -type f  )
> do
>   f1=$f
>   f2=b/${f#*/}
>   echo "compare: $f1 $f2"
>   diff <(sed -e '$a\' $f1) <(sed -e '$a\' $f2) \
>       && echo '** are same' || echo '** are different'
> done && echo '** all are same' || echo '** all are different'
compare: a/file1.txt b/file1.txt
** are same
compare: a/file2.txt b/file2.txt
** are same
** all are same
Run Code Online (Sandbox Code Playgroud)