I want a command (or probably an option to cp) that creates the destination directory if it does not exist.
Example:
cp -? file /path/to/copy/file/to/is/very/deep/there
I want a command (or probably an option to cp) that creates the destination directory if it does not exist.
Example:
cp -? file /path/to/copy/file/to/is/very/deep/there
Short Answer
To copy
myfile.txt
to/foo/bar/myfile.txt
, use:How does this work?
There's a few components to this, so I'll cover all the syntax step by step.
The mkdir utility, as specified in the POSIX standard, makes directories. The
-p
argument, per the docs, will cause mkdir tomeaning that when calling
mkdir -p /foo/bar
, mkdir will create/foo
and/foo/bar
if/foo
doesn't already exist. (Without-p
, it will instead throw an error.The
&&
list operator, as documented in the POSIX standard (or the Bash manual if you prefer), has the effect thatcp myfile.txt $_
only gets executed ifmkdir -p /foo/bar
executes successfully. This means thecp
command won't try to execute ifmkdir
fails for one of the many reasons it might fail.Finally, the
$_
we pass as the second argument tocp
is a "special parameter" which can be handy for avoiding repeating long arguments (like file paths) without having to store them in a variable. Per the Bash manual, it:In this case, that's the
/foo/bar
we passed tomkdir
. So thecp
command expands tocp myfile.txt /foo/bar
, which copiesmyfile.txt
into the newly created/foo/bar
directory.Note that
$_
is not part of the POSIX standard, so theoretically a Unix variant might have a shell that doesn't support this construct. However, I don't know of any modern shells that don't support$_
; certainly Bash, Dash, and zsh all do.A final note: the command I've given at the start of this answer assumes that your directory names don't have spaces in. If you're dealing with names with spaces, you'll need to quote them so that the different words aren't treated as different arguments to
mkdir
orcp
. So your command would actually look like:with all my respect for answers above, I prefer to use rsync as follow:
example:
This does it for me
Here's one way to do it:
dirname
will give you the parent of the destination directory or file. mkdir -p `dirname ...` will then create that directory ensuring that when you call cp -r the correct base directory is in place.The advantage of this over --parents is that it works for the case where the last element in the destination path is a filename.
And it'll work on OS X.