0

Using Cygwin on Windows 10, I am trying to find files in one directory (dir1) that are not in another (dir2), regardless of the file path

The idea is to loop through all files in dir1 and, for each, launch a find command in dir2 and display only the missing files:

for f in `ls -R /path/to/dir1` ; do
  if [ $( find /path/to/dir2 -name "$f" | wc -l ) == 0 ] ; then
    echo $f
  fi
done

The problem is that some of the file names have spaces in them and this is causing the find command to fail

Any ideas?

BNT
  • 11
  • 1
  • 7
  • 1
    In terms of what you are trying to do, this is a duplicate of https://stackoverflow.com/questions/11440332/in-bash-find-all-files-in-flat-directory-that-dont-exist-in-another-directory-t/57430600#57430600 – Jon Aug 09 '19 at 12:59
  • I'll second that, and just note that there's really nothing Cygwin-specific about this question, except to the extent that filenames containing spaces may be slightly more common on Windows (but really could be anywhere). Most questions you have like this will be common to `bash`, `find`, etc. on any platform. There are only a few areas I can think of where there are some Cygwin-specific caveats, including file permissions, symlinks, and handling Windows-style filenames. But mostly you'll have better luck finding answers if you *don't* specify Cygwin in your search. Good luck! – Iguananaut Aug 12 '19 at 08:09

1 Answers1

0

Could you do this with find and comm? Something like the following should print files in dir1 which aren't in dir2.

comm -23 <(find dir1 -type f -printf '%f\n' | sort -u) <(find dir2 -type f -printf '%f\n' | sort -u)

It works with spaces, too:

$ mkdir dir1 dir2
$ touch dir1/foo dir1/bar
$ touch dir2/foo dir2/baz
$ touch dir1/'foo bar'
$ comm -23 <(find dir1 -type f -printf '%f\n' | sort -u) <(find dir2 -type f -printf '%f\n' | sort -u)
./bar
./foo bar

For real safety, you should use NUL-terminated strings, so filenames with newlines in will work.

comm -z23 <(find dir1 -type f -printf '%f\0' | sort -uz) <(find dir2 -type f -printf '%f\0' | sort -uz) | xargs -0 printf '%s\n'
Jon
  • 3,573
  • 2
  • 17
  • 24