如何使'diff -X'忽略特定路径而不是文件名?


28

正在做: 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)。


男人diff--exclude选择是如此低劣的...
Elouan Keryell,即使

Answers:


30

列出目录应该起作用;例如,这是我在脚本中使用的(假设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,则diff必须生成要列表的文件(例如,使用find),并比较要从这些路径派生的文件;例如,给定

$ 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(除了regexp也可以在这里使用,例如.*/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
谢谢,但我认为您错过了重点。似乎唯一的支持是使用“ base-name”时。那可以是目录或文件的名称。无论哪种情况,diff都会忽略您的要求。使用路径时会出现问题。例如,我不能让diff忽略/ an / absolute / path / to / a / file或./a/relative/path/to/a/file。
2013年

2
diff --exclude =“ / this / specific / file / that / im / explicitly / pending / you / to / ignore”。它不会工作。
2013年

3
正确,exclude模式与文件的基本名称匹配(按照gnu.org/software/diffutils/manual/html_node/…);路径将不起作用(如中的所示foo/bar.txt)。为此,您可能必须运行find以生成文件名列表,并导出要比较的文件的路径。
迈克尔

更新了答案,以包括从中排除文件路径的示例diff,而不仅仅是使用basename
michael

好的,我明白您的建议,但似乎有问题。我还需要考虑目录,而不仅仅是文件(即-type f)。现在,尽管您仍然可以使用regexp修剪某些文件find,如果输入diff包含一个目录,它将通过该目录中的文件进行比较,并且其中一些文件可能需要忽略。回到正方形
Ash


1

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

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

但是,尽管它适用于单个排除项,但对于像您这样的长忽略列表来说,它不可能。


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

1
尽管这可以回答问题,但是如果您可以提供解释为什么会这样做会更好。
DavidPostill
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.