0

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?

3
  • files are distinct because of their filenames, I assume?
    – Jeff Schaller
    Jun 3, 2019 at 14:53
  • Yes, that is the case.
    – mywayz
    Jun 3, 2019 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, 2019 at 23:33

2 Answers 2

0

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

Setup:

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

3 directories, 6 files


cd folderA
A=(*)
cd ../folderB
B=(*)
cd ..

Execution:

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

Result:

$ tree folderC
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.

0

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'

You must log in to answer this question.

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