如何让“diff -X”忽略特定路径而不是文件名?

如何让“diff -X”忽略特定路径而不是文件名?

正在做: diff -r -X <ignore-list> <src-dir> <dest-dir>

如果它们是以下形式,则似乎不会diff忽略中的条目。<ignore-list><dir>/<file>

但是,形式为 > 的条目会被考虑。这是一个问题,因为我可能在不同的子目录中<file有多个文件,其中一些我不想被忽略。<file>

两者的手册页中似乎都没有太多关于模式语法的信息diff。据我所知,它只是 diff 所考虑的文件的基本名称(请参阅http://forums.gentoo.org/viewtopic-t-889788-start-0.html如果你有兴趣的话)。

答案1

列出目录应该可以工作;例如,这是我在脚本中使用的(假设是 gnu diff),

diff -r \
   --exclude="*~" \
   --exclude=".svn" \
   --exclude=".git" \
   --exclude="*.zip*" \
   --exclude="*.gz" \
   --exclude="*.tar" \
   ...etc

...它忽略.svn.git目录的内容,也忽略名为*.zip/ *.gz/etc 的单个文件。

编辑:为了过滤形式为 的路径dir_a/file1,但仍diff包含具有相同基本名称的文件,例如dir_b/file1或,则必须生成dir_a/b/file1一个文件列表(例如,使用),并从这些路径派生出要比较的文件;例如,给定difffind

$ find ONE TWO -type f -print 
ONE/a/1.txt
ONE/a/2.txt
ONE/a/b/2.txt
TWO/a/1.txt
TWO/a/2.txt
TWO/a/b/2.txt

你生成要比较的文件列表,例如排除*/a/2.txt但仍比较名为 的其他文件2.txt。只需“查找”除 之外的所有文件ONE/a/2.txt(这里也可以使用正则表达式,例如.*/a/2.txt

$ find ONE -type f \( ! -regex 'ONE/a/2.txt' \) \
    -exec bash -c 'diff -q "${1}" "${2/ONE/TWO}"' - {} {} \;  

实际上忽略了ONE/a/2.txt(和TWO/a/2.txt),但仍比较名为的其他文件2.txt

diff -q ONE/a/1.txt TWO/a/1.txt
diff -q ONE/a/b/2.txt TWO/a/b/2.txt

编辑:或者,更有趣的是find(留给读者练习更多的乐趣),选择文件或目录排除然后diff其他的:

$ find ONE \( -regex 'ONE/a/2.txt' -o -name b  -prune \)  \
    -o -type f -exec bash -c 'echo diff -q "${1}" "${2/ONE/TWO}"' - {} {} \

上述示例排除了特定文件“{top}/a/2.txt”、任何名为“b”的目录,其他所有内容均已差异化。(除了简单的“ -name b”,您还可以使用“ -regex '.*/b'” - 注意,没有尾随的“/”。)

答案2

为了排除目录directory/sub-directory,我使用

diff -r <src-dir> <dest-dir> | grep -v directory/sub-directory

但是,尽管它应该适用于单个排除,但它不可能适用于像您那样的长忽略列表。

答案3

我遇到了同样的问题,所以我为 制作了一个补丁diff。该补丁尚未被接受,但您可以使用diff该补丁或使用 AUR 包在 Arch Linux 上安装

这里diff补丁。

答案4

$ diff -rq foo.orig foo | grep -vP 'ignore1/|exclude2/' | awk '{print $2}' | cut -d'/' -f2- | xargs -I{} diff -u foo.orig/{} foo/{}

相关内容