18

Are there any Linux/Unix tools which find all the files in one directory not present in another? Basically I'm looking for diff which works on the output of ls.

Short and sweet scripts are also appreciated.

8 Answers 8

23

diff does this already:

diff dir1 dir2

Example output:

Only in dir1: some_file.txt
Only in dir1: some_other_file.txt
Only in dir2: third_file.txt
2
  • 5
    This is good. One gripe: diff is actually running on each of the files that are in both. Is there an obscure option to just run against file names (I may have missed it)? Otherwise, I suggest diff dir1 dir2 | grep "Only" Sep 1, 2010 at 16:12
  • wow this just save me many minutes of bash scripting thanks Feb 18, 2020 at 12:51
14

Bash:

diff <(cd dir1; ls) <(cd dir2; ls)

Compare only the filenames - not the contents of the files.

6
  • Also ksh and zsh. Sep 1, 2010 at 18:37
  • use rsync for sync dirs
    – c4f4t0r
    Sep 4, 2017 at 13:02
  • 1
    Do not parse ls, use find instead! Feb 11, 2020 at 20:39
  • @valisstillwithMonica: This isn't an example of parsing ls since it's only getting a list of files and not looking at fields in output such as ls -l. It's also not parsing the names themselves so special characters aren't a problem except for newlines. But diff is going to treat parts of file names surrounding newlines separately anyway (even this answer with grep Only fails in this regard). Jun 28, 2022 at 21:56
  • can this be made to be recursive?
    – majorgear
    May 23, 2023 at 14:57
4

Like people told you here, you can use DIFF in various usage variations. Or you just use dirdiff instead, which is meant for what you're trying! :-)

But if you want to keep some directories in sync then you really should take a look on rsync.

Regards

4

If you are wanting to do this through all sub directories as well, a good way to do it is:

diff --brief -r dir1/ dir2/

I prefer using brief, but you can leave that out if you want.

1
  • This is exactly what I was looking for but found WAY more files than I anticipated. Is there any way to copy the files found in dir2/ to a new folder? dir3/
    – trex005
    Aug 20, 2022 at 19:33
1

for i in $(ls -1 directory1); do if (test -f directory2/$i) then echo $i; fi; done

1

Dennis Williamson had a good answer, but I needed to do this recursively. GNU findutils 4.7.0 doesn't sort its output, so here's what I used

diff <(cd $dir1; find | sort) <(cd $dir2; find | sort)

To do this only one way, and produce a list of files, I used this:

diff <(cd $dir1; find | sort) <(cd $dir2; find | sort) \
| grep '< ./' | sed "s,< ./,$dir1/,"

For this to work properly, neither $dir1 nor $dir2 should include the trailing slash.

0

This works..

ls -a1 /dir1 | sort > /tmp/1
ls -a1 /dir2 | sort > /tmp/2
diff /tmp/1 /tmp/2
0

untested:

find /dir/A -printf "%P" | while read f; do
  if [ ! -e "/dir/B/$f" ]; then
    echo $f
  fi
done

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .