Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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

share|improve this question

5 Answers 5

up vote 14 down vote accepted

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/
share|improve this answer

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.

share|improve this answer
1  
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 at 19:48

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

pax -rws':^:dest/dir/:' file .
share|improve this answer
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 at 19:41

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.

share|improve this answer
2  
You need rsync -R to preserve the directory heirarchy –  glenn jackman May 6 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 at 20:10
1  
At least the GNU cp has the --parents option. –  peterph May 6 at 20:45
1  
@peterph Indeed, but then you're restricted in the naming of the target directory –  mjturner May 7 at 7:49
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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.