How to copy retaining relative path

Problem

From a certain directory I wanted to copy a file a/b/c.txt to a destination. But I wanted the relative path a/b to be retained at the destination. A normal copy would just copy c.txt to the destination.

Solution

There is no way to do this using the cp command. One solution is to use rsync which supports maintaining the relative file path.

For example:

$ pwd
/home/joe/workspace/foobar
$ rsync -R a/b/c.txt /home/joe/destination

This copies c.txt to /home/joe/destination/a/b automatically creating a/b if they do not exist in the destination.

Advertisements

Trailing slash in rsync

RSync has some different and confusing behavior depending on whether you put a trailing slash on the source directory or not.

  • No trailing slash on source directory: this copies the source directory itself as a subdirectory into the destination directory.

For example:

$ rsync -a /some/path/foobar .
$ ls
foobar/
  • Trailing slash on source directory: this copies the contents inside source directory into the destination directory.

For example:

$ rsync -a /some/path/foobar/ .
$ ls
content.txt
of.txt
foobar.txt

You do not see such confusing behavior with cp or mv. I guess rsync has this because it is usually used for synchronizing the contents of two directories but it is also sometimes used to copy over directories.

How to one-way sync using rsync on Ubuntu

rsync is an excellent program to perform one-way sync between directories.

If both the source and destination directories are on local storage:

$ rsync -av /home/joe/from-dir /media/backup/to-dir

To make the destination a strict mirror copy, thus deleting any extra files it may have:

$ rsync -av --delete /home/joe/from-dir /media/backup/to-dir

If one or both of the source and destination is not on local storage, then rsync can be asked to use compression to save transfer time:

$ rsync -avz /home/joe/from-dir /mars/great-valley/to-dir

Tried with: rsync 3.0.9 and Ubuntu 12.04.1 LTS