38

I am trying to do something along the lines of:

diff `ls -1a ./dir1` `ls -1a ./dir2`

But that doesn't work for obvious reasons. Is there a better way of achieving this (in 1 line), than this?

ls -1a ./dir1 > lsdir1
ls -1a ./dir2 > lsdir2
diff lsdir1 lsdir2

Thanks

bguiz
  • 2,041
  • 5
  • 22
  • 33

4 Answers4

62

You were close. In bash you want process substitution, not command substitution:

diff <(ls -1a ./dir1) <(ls -1a ./dir2)
Ignacio Vazquez-Abrams
  • 111,361
  • 10
  • 201
  • 247
  • Process substitution is not necessary, though. The answer below (https://superuser.com/a/228773/566289) is on point! – Jan D May 05 '19 at 12:00
  • 4
    Except that answer diffs the content, not the filenames! – lost Aug 14 '19 at 13:14
11
diff -rq dir1 dir2

using the -r option, walk entire directory trees, recursively checking differences between subdirectories and files that occur at comparable points in each tree. The trick is to use the -q option to suppress line-by-line comparisons

fseto
  • 1,357
  • 8
  • 14
  • 6
    @festo : You wree missing the poitn of this question, I don't actually want to diff the contents of the files, I want to diff the output of the `ls` commands – bguiz Jan 04 '11 at 02:53
  • +1, Actually, I got the same output with the one caveat, diff -rq reported a linked file as 'No such file or directory'. So, plus one for correct, and frankly simpler usage. (even if IVA's answer is a better 'learning opportunity' for process substitution (>_<) – xtian Oct 18 '13 at 00:40
  • 1
    This is *much* slower than diffing the file names: the entirety of every file has to be read and compared. – Zaz Sep 30 '14 at 20:39
  • @Josh of course, because it does recursively.... – Braiam Oct 06 '14 at 19:37
  • 1
    @Braiam: Even if you recursively diff the file names (using `rsync` with the `--dry-run` option, for example), it would still be much faster than `diff -r`. – Zaz Oct 11 '14 at 12:36
0

Neither answers did the work for me as :

  1. I needed the diff to be recursive
  2. My folders were not side by side

Inspired from @Ignacio Vazquez-Abrams I used :

diff <(find PATH1 | sed 's"PATH1""') <(find PATH2 | sed 's"PATH2""')

Which does the job just fine and can be adapted for a nifty script :

#!/bin/bash
# Usage : compDirs dir1 dir2
# compare the file/folder names recursively in Dir1 and Dir2
 
PATH1=$1 
PATH2=$2

diff <(find $PATH1 | sed "s#$PATH1##") <(find $PATH2 | sed "s#$PATH2##")
cmbarbu
  • 139
  • 5
  • A variant without sed would be `diff <(cd $PATH1 && find .) <(cd $PATH2 && find .)`. As these are subprocesses the cd won't propagate to parent processes. – VRehnberg Dec 20 '22 at 09:44
0

Expanding on this, since I don't have enough points to comment, the options -y (to show in two columns) and --suppress-common-lines make it even better!

diff -y --suppress-common-lines <(ls -1a ./dir1) <(ls -1a ./dir2)

You can remove -a from ls parts if not interested in dot/hidden files.

Máté Juhász
  • 21,403
  • 6
  • 54
  • 73
Unknown
  • 5
  • 3