21

I want to cp aaa/deep/sea/blob.psd to bbb/deep/sea/blob.psd

How do I do the copy if the deep and sea directories don't exist under bbb so that the copy both creates the directories that are needed and copies the file?

Right now I get
No such file or directory as deep and sea don't exist.

I looked thru the man help pages and other questions but nothing jumps out at me.

The closest I've got is using rcp for the directory:

rcp -r aaa/deep/sea/ bbb/deep/sea/

though this copies the whole directory and contents and I just want the one file. Trying to do that however gave cp: cannot create regular file bbb/deep/sea/blob.psd' such file or directory

20

Try to use such next function for such situation:

copy_wdir() { mkdir -p -- "$(dirname -- "$2")" && cp -- "$1" "$2" ; }

and use it as

copy_wdir aaa/deep/sea/blob.psd bbb/deep/sea/blob.psd

By the way, GNU cp has a --parents option. It's really close to what you want, but not exactly.
It will also create aaa directory that seems you don't need. However you can first cd to aaa and copy like:

cd aaa && cp --parents deep/sea/blob.psd ../bbb/
26

It's easy using the install program from the coreutils that is typically used for this very purpose by build systems like automake:

install -D /path/to/source /path/to/destination

Note that install creates all parts of the path just like mkdir -p does, see man install. I'm curious why you didn't include why you want to do that. Calling mkdir and cp is very easy.

  • 2
    I think there are a lot of good answers on this question, but this one gets my vote as it's the most portable. The rsync answer will only create 1 directory, and pax doesn't seem to be common. – Patrick May 6 '14 at 19:48
  • Use -d instead of -D on a Mac. – Matt M. Nov 14 '16 at 23:01
  • note that this command creates the destination files with 755 (rwxr-xr-x) permissions, which is probably not desired. you can specify something else with the -m switch, but I could not find a way to just keep the file permissions :( – törzsmókus Jan 9 at 19:19
7

With standard (POSIX/Unix) commands, you've got:

pax -rws ':^:dest/dir/:' file .
  • 1
    Interesting. I'd never heard of pax before. Though I like its concept. Unfortunately even though it's in POSIX, it seems very few distros install it by default :-( – Patrick May 6 '14 at 19:41
  • @Patrick - if you skip all the way to the end of info tar - somewhere around the portability concerns section - i think youll find that GNU tar claims to be fully pax compatible. I did anyway, though i have never yet got around to putting those claims to a test. – mikeserv Oct 9 '14 at 6:01
6

I'm not aware of a way of doing it using cp, but it's certainly possible using rsync:

$ rsync sourcefile dir/

where dir is a directory that does not have to exist. There are lots of other ways of achieving the same using other commands.

  • 3
    You need rsync -R to preserve the directory heirarchy – glenn jackman May 6 '14 at 19:59
  • @glennjackman Indeed, 'proper' use of rsync needs more options, but the question was simply about creating a non-existent target directory, hence my brief answer :) – mjturner May 6 '14 at 20:10
  • 1
    At least the GNU cp has the --parents option. – peterph May 6 '14 at 20:45
  • 2
    @peterph Indeed, but then you're restricted in the naming of the target directory – mjturner May 7 '14 at 7:49
5
cd aaa
pax -rw deep/sea/blob.psd ../bbb

If you don't have pax (it's mandated by POSIX, as a standard replacement of cpio and tar which had too many incompatibilities to standardize), use cpio -p or tar -cf - … | tar -xf - instead.

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.