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
5 Answers 5
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.
-
2I 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, andpax
doesn't seem to be common.phemmer– phemmer2014年05月06日 19:48:05 +00:00Commented May 6, 2014 at 19:48 -
Use
-d
instead of-D
on a Mac.Matt M.– Matt M.2016年11月14日 23:01:22 +00:00Commented Nov 14, 2016 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– törzsmókus2019年01月09日 19:19:35 +00:00Commented Jan 9, 2019 at 19:19
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/
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.
-
3You need
rsync -R
to preserve the directory heirarchyglenn jackman– glenn jackman2014年05月06日 19:59:25 +00:00Commented May 6, 2014 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– mjturner2014年05月06日 20:10:27 +00:00Commented May 6, 2014 at 20:10 -
1At least the GNU
cp
has the--parents
option.peterph– peterph2014年05月06日 20:45:34 +00:00Commented May 6, 2014 at 20:45 -
2@peterph Indeed, but then you're restricted in the naming of the target directorymjturner– mjturner2014年05月07日 07:49:05 +00:00Commented May 7, 2014 at 7:49
With standard (POSIX/Unix) commands, you've got:
pax -rws ':^:dest/dir/:' file .
-
1Interesting. 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 :-(phemmer– phemmer2014年05月06日 19:41:02 +00:00Commented May 6, 2014 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 GNUtar
claims to be fullypax
compatible. I did anyway, though i have never yet got around to putting those claims to a test.mikeserv– mikeserv2014年10月09日 06:01:37 +00:00Commented Oct 9, 2014 at 6:01
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.