0

I would like to move a directory and all its contents ontop of another.

By this I mean, that if I have two directories, A and B and I want to move B onto A, I want files and directories that are not in A but are in B to be simply copied across to A, files of the same name in A to be updated to the copies in B, and folders of the same name in A to be updated with new contents from B but otherwise have existing contents retained

Is there a way to do this easily in bash?

Incidentally, it is my understanding that this is what happens when you extract a tar archive over an older version of that archive. Is this true?

nedned
  • 151
  • 7

3 Answers3

1

You're on the right track with tar. This command will do what you want:

$ cd /path/to/A
$ tar -cf - * | tar -C /path/to/B -xf -

I've also seen cpio or rsync used for this purpose.

Here's an example run with tar:

/tmp $ tree A B
A
|-- one
|   `-- two
|       |-- four
|       `-- three
`-- uno
    `-- hello
B
|-- dos
|   |-- hi
|   `-- tres
`-- one
    `-- two
        `-- three

7 directories, 5 files
/tmp $ md5sum A/one/two/three B/one/two/three 
764efa883dda1e11db47671c4a3bbd9e  A/one/two/three
d41d8cd98f00b204e9800998ecf8427e  B/one/two/three
/tmp $ (cd A; tar -cf - * | tar -C ../B -xf -)
/tmp $ tree A B
A
|-- one
|   `-- two
|       |-- four
|       `-- three
`-- uno
    `-- hello
B
|-- dos
|   |-- hi
|   `-- tres
|-- one
|   `-- two
|       |-- four
|       `-- three
`-- uno
    `-- hello

8 directories, 7 files
/tmp $ md5sum A/one/two/three B/one/two/three 
764efa883dda1e11db47671c4a3bbd9e  A/one/two/three
764efa883dda1e11db47671c4a3bbd9e  B/one/two/three
/tmp $ 

Hope that helps!

Mike Mazur
  • 6,133
  • 2
  • 20
  • 13
  • Awesome, that's exactly what I was after. I'm surprised there' not a more direct way of doing it though. – nedned Nov 19 '09 at 12:41
  • Although I think you got the names of the directories the wrong way round. A is the folder that should have B's contents applied to it. So A should end up being bigger, not B. – nedned Nov 19 '09 at 12:42
  • Right, I took a closer look at your question and indeed got A and B switched around. That's easy enough to fix :) – Mike Mazur Nov 20 '09 at 02:12
1
rsync -a -v -n /path/to/a/ /path/to/b/

If everything looks ok, remove the -n flag make it actually do the work. If you don't want it to be so chatty, remove the -v flag.

Edit: to be precise, this makes b have everything that a has, plus keep everything b had before.

Rudedog
  • 732
  • 5
  • 9
  • This one is even nicer as it's a bit more obvious from the command what's going on, plus you get a report of which files were updated. Thanks :) – nedned Nov 20 '09 at 03:38
0

It sounds like you want to synchronize too directories.

It does take a bit more setup, but if you want to frequently do this you may want to look at unison. Here is an article describing the setup.

Zoredache
  • 130,897
  • 41
  • 276
  • 420
  • I don't actually want to synchronize them, I want to update one directory with the new contents of a second directory, but I don't actually care about updating the second directory - it will be deleted afterwards. – nedned Nov 20 '09 at 03:26