Search code examples
linuxbashshellcommand-linediff

diff: Only compare files and ignore subdirectories


I'm trying to compare two directories, each with some files and a subdirectory. Is there any way to run diff on these two folders, but not run it on the subdirectory? I've tried using diff -x'*/' foo bar, as well as a couple variants with backslashes to escape them, but no dice.

The actual name of the subdirectory can change, which is why I don't want to specify an exact name pattern.

Thanks!


Solution

  • If you are already diffing two specific directories, then I assume you know their names. In this case all you need to determine dynamically is the list of sub-directories contained in each.

    Assuming you are in a parent directory; you have a structure like so, and you want to diff foo and bar but you want to exclude baz and quux:

    +-- foo/
    |     |-- baz/
    |     |
    |     +-- file.txt
    |
    +-- bar/
          |-- quux/
          |
          +-- file.txt
    

    Using find:

    find * -mindepth 1 -type d
    

    Yields a list of subdirs inside foo and bar:

    foo/baz
    bar/quux
    

    At this point you could write this to a temporary file:

    find * -mindepth 1 -type d > exclude.txt
    

    And then use diff's -X flag, which allows you to specifies a file containing patterns to exclude from a diff.

    This won't quite work however, because you'll need to slice the parent dir name off each result. We can use cut to do this:

    find * -mindepth 1 -type d | cut -d'/' -f2 > exclude.txt
    

    This yields the following:

    baz
    quux
    

    So you can now use:

    diff -X exclude.txt foo bar
    

    Or, if you don't want to create a temporary file you can do it as a one-liner:

    diff -uX <(find * -mindepth 1 -type d | cut -d'/' -f2) foo bar
    

    Hope this helps :)