I have two folders - Folder A and Folder B.

I compared the files from both folders using diff command. Now after finding that certain files are only available in Folder A and Certain files in Folder B, I would like copy those distinctive files from both folders into 1 folder called folder C which will now have all the unique files from both A and B

How can I do this?

  • files are distinct because of their filenames, I assume? – Jeff Schaller Jun 3 at 14:53
  • Yes, that is the case. – mywayz Jun 3 at 15:25
  • Is there a penalty to copying files that exist in both places? The simplest way is mkdir folderC; cp -p folderA/* folderB/* folderC/. If there is a penalty, then rsync is easy: mkdir folderC; rsync -av folderA/ folderC; rsync -av folderB/ folderC/. – Jim L. Jun 3 at 23:33

You could use zsh's array subtraction and brace expansion features, like so:


$ tree .
├── folderA
│   ├── file0
│   ├── file1
│   └── file2
├── folderB
│   ├── file2
│   ├── file3
│   └── file4
└── folderC

3 directories, 6 files

cd folderA
cd ../folderB
cd ..


cp folderA/${^A:|B} folderB/${^B:|A} folderC


$ tree folderC
├── file0
├── file1
├── file3
└── file4

0 directories, 4 files

The two setup steps create arrays (named A and B) that contain the filenames in folders A and B, respectively.

The execution step asks cp to copy the expansion of the A array minus the B array, all prefixed with folderA as well as the corresponding expansion of the B array minus the A array (all prefixed with folderB) into folderC.


A hacky solution using diff, sed and xargs:

Test setup:

$ mkdir folderA folderB folderC
$ touch folderA/fi\ le1 folderA/file2 folderA/file3 folderB/file3 folderB/file4
$ diff -rq folderA folderB
Only in folderA: fi le1
Only in folderA: file2
Only in folderB: file4

Now we use sed to filter all lines starting with string Only in folderA: and we change this part to folderA/ to form a relative filename with quotes ('folderA/fi le1'). This string is then piped to xargs and used to copy this file to folderC.

$ diff -rq folderA folderB | sed -n "s/^Only in \(folderA\): \(.*\)/'\1\/\2'/p" | xargs cp -vt folderC
'folderA/fi le1' -> 'folderC/fi le1'
'folderA/file2' -> 'folderC/file2'

The same as above for folderB:

$ diff -rq folderA folderB | sed -n "s/^Only in \(folderB\): \(.*\)/'\1\/\2'/p" | xargs cp -vt folderC
'folderB/file4' -> 'folderC/file4'

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.