How can I make 'diff -X' ignore specific paths and not file names?
Listing directories should work; e.g., here's what I've used in a script (assuming gnu diff),
diff -r \
--exclude="*~" \
--exclude=".svn" \
--exclude=".git" \
--exclude="*.zip*" \
--exclude="*.gz" \
--exclude="*.tar" \
...etc
...which ignores contents of .svn
and .git
dirs, but also individual files named *.zip
/*.gz
/etc.
Edit: In order to filter paths of the form dir_a/file1
but still diff
files with the same basename, such as dir_b/file1
or dir_a/b/file1
, then a list of files to diff
would have to be generated (for example, using find
), and the file to compare derived from these paths; e.g., given
$ 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
you generate the list of files to compare, excluding for example */a/2.txt
but still comparing other files named 2.txt
. Just "find" all files except ONE/a/2.txt
(a regexp can also be used here, such as .*/a/2.txt
)
$ find ONE -type f \( ! -regex 'ONE/a/2.txt' \) \
-exec bash -c 'diff -q "${1}" "${2/ONE/TWO}"' - {} {} \;
which in effect ignores ONE/a/2.txt
(and TWO/a/2.txt
), but still compares the other files named 2.txt
:
diff -q ONE/a/1.txt TWO/a/1.txt
diff -q ONE/a/b/2.txt TWO/a/b/2.txt
Edit: Or, more fun with find
(additional fun left as an exercise for the reader), select the files or directories to exclude and then diff
everything else:
$ find ONE \( -regex 'ONE/a/2.txt' -o -name b -prune \) \
-o -type f -exec bash -c 'echo diff -q "${1}" "${2/ONE/TWO}"' - {} {} \
The above example excludes the specific file "{top}/a/2.txt", any directory named "b", and everything else is diff'd. (Instead of simple "-name b
" you could also use "-regex '.*/b'
" - note, no trailing "/".)
I had the same problem so I created a patch to diff
. The patch has yet to be accepted, but you can build your own version of diff
with the patch or install on Arch Linux with an AUR package.
Here is the diff
patch.
To exclude directory directory/sub-directory
, I use
diff -r <src-dir> <dest-dir> | grep -v directory/sub-directory
However, although it should work for a single exclude, it should not be possible for a long ignore list as you have.