• 2 main folders, that may have subfolders with the same names (I do not know what names might be duplicated, that's what I am trying to find)
  • the subfolders have MANY other files & subfolders so tools with automatic recursion are not really an option
  • I only care about duplicate subfolder names on the first level of the two main folders
  • contents of the subfolders don't matter
  • contents of the files don't matter

I tried using meld GUI but that just takes endless time to finish for these structures.

I tried using diff --brief --report-identical-files folder1 folder2 but that basically reports everything and it does not even include the folders so I can't even | grep identical.

Am I using wrong tools? Or is there some trick that I didn't get from diff --help ? Or am I doing something wrong?



I'd use a simple find:

find "/path/to/main1" "/path/to/main2" -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | sort | uniq -d

Or to make it zero-terminated to prevent issues with newline characters:

find "/path/to/main1" "/path/to/main2" -mindepth 1 -maxdepth 1  -type d -printf '%f\0' | sort -z | uniq -zd | xargs -0
  • @jave.web don't copy: make a new folder, then make symlinks to your two target directories in this new folder and use find -L /path/to/new/folder -mindepth .... (the -L tells find to follow symlinks). This way you don't need to duplicate the data.
    – terdon
    Dec 8 '21 at 15:22
  • Ok, after the edit, it works exactly as expected. (Note if you want same for files use -type f instead of -type d. @terdon thanks for the suggestion that's certainly an approach too
    – jave.web
    Dec 8 '21 at 15:24

Using zsh, given

% tree dir1 dir2
├── bar
└── foo
    └── baz
├── bar
│   └── baz
└── baz

6 directories, 0 files


% a=( dir1/*(/ND:t) ) ; b=( dir2/*(/ND:t) )

creates arrays of the tails (basenames) of directories / in the two top-level directories dir1 and dir2 (with Dotglob and Nullglob options enabled).

Then we can use an expansion of the form ${name:*arrayname} to retain only elements that are present in both arrays:

% print -rC1 ${a:*b}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.