Linux:如果目标目录不存在,则复制并创建它
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1529946/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Linux: copy and create destination dir if it does not exist
提问by flybywire
I want a command (or probably an option to cp) that creates the destination directory if it does not exist.
如果目标目录不存在,我想要一个创建目标目录的命令(或者可能是 cp 的一个选项)。
Example:
例子:
cp -? file /path/to/copy/file/to/is/very/deep/there
采纳答案by Michael Krelin - hacker
mkdir -p "$d" && cp file "$d"
(there's no such option for cp
).
(没有这样的选项cp
)。
回答by Andy Ross
Shell function that does what you want, calling it a "bury" copy because it digs a hole for the file to live in:
Shell 函数可以做你想做的事,称它为“埋葬”副本,因为它为文件挖了一个洞:
bury_copy() { mkdir -p `dirname ` && cp "" ""; }
回答by Paul Whipp
If both of the following are true:
如果以下两种情况都为真:
- You are using the GNU version of
cp
(and not, for instance, the Mac version), and - You are copying from some existing directory structure and you just need it recreated
- 您使用的是 GNU 版本
cp
(而不是,例如 Mac 版本),并且 - 您正在从一些现有的目录结构复制,您只需要重新创建它
then you can do this with the --parents
flag of cp
. From the info page (viewable at http://www.gnu.org/software/coreutils/manual/html_node/cp-invocation.html#cp-invocationor with info cp
or man cp
):
然后你可以用这样做--parents
的标志cp
。从信息页面(可在http://www.gnu.org/software/coreutils/manual/html_node/cp-invocation.html#cp-invocation或使用info cp
或查看man cp
):
--parents Form the name of each destination file by appending to the target directory a slash and the specified name of the source file. The last argument given to `cp' must be the name of an existing directory. For example, the command: cp --parents a/b/c existing_dir copies the file `a/b/c' to `existing_dir/a/b/c', creating any missing intermediate directories.
--parents Form the name of each destination file by appending to the target directory a slash and the specified name of the source file. The last argument given to `cp' must be the name of an existing directory. For example, the command: cp --parents a/b/c existing_dir copies the file `a/b/c' to `existing_dir/a/b/c', creating any missing intermediate directories.
Example:
例子:
/tmp $ mkdir foo
/tmp $ mkdir foo/foo
/tmp $ touch foo/foo/foo.txt
/tmp $ mkdir bar
/tmp $ cp --parents foo/foo/foo.txt bar
/tmp $ ls bar/foo/foo
foo.txt
回答by Jamie McCrindle
Here's one way to do it:
这是一种方法:
mkdir -p `dirname /path/to/copy/file/to/is/very/deep/there` \
&& cp -r file /path/to/copy/file/to/is/very/deep/there
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.
dirname
将为您提供目标目录或文件的父级。mkdir -p `dirname ...` 然后将创建该目录,确保当您调用 cp -r 时,正确的基本目录就位。
The advantage of this over --parents is that it works for the case where the last element in the destination path is a filename.
与 --parents 相比,它的优势在于它适用于目标路径中的最后一个元素是文件名的情况。
And it'll work on OS X.
它可以在 OS X 上运行。
回答by help_asap
Such an old question, but maybe I can propose an alternative solution.
这么老的问题,但也许我可以提出一个替代解决方案。
You can use the install
programme to copy your file and create the destination path "on the fly".
您可以使用该install
程序来复制您的文件并“即时”创建目标路径。
install -D file /path/to/copy/file/to/is/very/deep/there/file
There are some aspects to take in consideration, though:
但是,有一些方面需要考虑:
- you need to specify also the destination file name, not only the destination path
- the destination file will be executable(at least, as far as I saw from my tests)
- 您还需要指定目标文件名,而不仅仅是目标路径
- 目标文件将是可执行的(至少,就我从测试中看到的而言)
You can easily amend the #2 by adding the -m
option to set permissions on the destination file (example: -m 664
will create the destination file with permissions rw-rw-r--
, just like creating a new file with touch
).
您可以通过添加在-m
目标文件上设置权限的选项轻松修改 #2 (例如:-m 664
将创建具有权限的目标文件rw-rw-r--
,就像使用 新建文件一样touch
)。
And here it is the shameless link to the answer I was inspired by=)
回答by Mark Amery
Short Answer
简答
To copy myfile.txt
to /foo/bar/myfile.txt
, use:
要复制myfile.txt
到/foo/bar/myfile.txt
,请使用:
mkdir -p /foo/bar && cp myfile.txt $_
How does this work?
这是如何运作的?
There's a few components to this, so I'll cover all the syntax step by step.
这有几个组成部分,所以我将逐步介绍所有语法。
The mkdirutility, as specified in the POSIX standard, makes directories. The -p
argument, per the docs, will cause mkdirto
POSIX 标准中指定的mkdir实用程序创建目录。的说法,每文档,会造成MKDIR到-p
Create any missing intermediate pathname components
创建任何缺少的中间路径名组件
meaning that when calling mkdir -p /foo/bar
, mkdirwill create /foo
and/foo/bar
if /foo
doesn't already exist. (Without -p
, it will instead throw an error.
这意味着在调用时mkdir -p /foo/bar
,mkdir将创建/foo
,/foo/bar
如果/foo
尚不存在。(没有-p
,它反而会抛出错误。
The &&
list operator, as documented in the POSIX standard(or the Bash manualif you prefer), has the effect that cp myfile.txt $_
only gets executed if mkdir -p /foo/bar
executes successfully. This means the cp
command won't try to execute if mkdir
fails for one of the many reasons it might fail.
该&&
列表操作,如记录在POSIX标准(或猛砸手动,如果你喜欢),有效果cp myfile.txt $_
只有得到执行,如果mkdir -p /foo/bar
执行成功。这意味着cp
如果由于可能失败的多种原因之一而mkdir
失败,该命令将不会尝试执行。
Finally, the $_
we pass as the second argument to cp
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:
最后,$_
我们作为第二个参数传递给的cp
是一个“特殊参数”,它可以方便地避免重复长参数(如文件路径),而不必将它们存储在变量中。根据Bash 手册,它:
expands to the last argument to the previous command
扩展到上一个命令的最后一个参数
In this case, that's the /foo/bar
we passed to mkdir
. So the cp
command expands to cp myfile.txt /foo/bar
, which copies myfile.txt
into the newly created /foo/bar
directory.
在这种情况下,这就是/foo/bar
我们传递给mkdir
. 所以cp
命令扩展为cp myfile.txt /foo/bar
,它复制myfile.txt
到新创建的/foo/bar
目录中。
Note that $_
is notpart 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.
请注意,$_
是不是POSIX标准的一部分,所以理论上Unix的变种可能具有不支持此构建物的外壳。但是,我不知道有任何不支持的现代 shell $_
;当然,Bash、Dash 和 zsh 都可以。
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
or cp
. So your command would actually look like:
最后一点:我在本答案开头给出的命令假定您的目录名称中没有空格。如果您正在处理带有空格的名称,则需要引用它们,以便不同的单词不被视为mkdir
或的不同参数cp
。所以你的命令实际上看起来像:
mkdir -p "/my directory/name with/spaces" && cp "my filename with spaces.txt" "$_"
回答by danuker
rsync file /path/to/copy/file/to/is/very/deep/there
This might work, if you have the right kind of rsync
.
如果您有正确的rsync
.
回答by Rich
cp
has multiple usages:
cp
有多种用途:
$ cp --help
Usage: cp [OPTION]... [-T] SOURCE DEST
or: cp [OPTION]... SOURCE... DIRECTORY
or: cp [OPTION]... -t DIRECTORY SOURCE...
Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.
@AndyRoss's answer works for the
@AndyRoss 的回答适用于
cp SOURCE DEST
style of cp
, but does the wrong thing if you use the
的样式cp
,但是如果您使用
cp SOURCE... DIRECTORY/
style of cp
.
的风格cp
。
I think that "DEST" is ambiguous without a trailing slash in this usage (i.e. where the target directory doesn't yet exist), which is perhaps why cp
has never added an option for this.
我认为“DEST”在这种用法中没有尾部斜杠是不明确的(即目标目录尚不存在的地方),这也许就是为什么cp
从未为此添加选项的原因。
So here's my version of this function which enforces a trailing slash on the dest dir:
所以这是我的这个函数的版本,它在 dest 目录上强制使用斜杠:
cp-p() {
last=${@: -1}
if [[ $# -ge 2 && "$last" == */ ]] ; then
# cp SOURCE... DEST/
mkdir -p "$last" && cp "$@"
else
echo "cp-p: (copy, creating parent dirs)"
echo "cp-p: Usage: cp-p SOURCE... DEST/"
fi
}
回答by SD.
Simply add the following in your .bashrc, tweak if you need. Works in Ubuntu.
只需在您的 .bashrc 中添加以下内容,根据需要进行调整。在 Ubuntu 中工作。
mkcp() {
test -d "" || mkdir -p ""
cp -r "" ""
}
E.g If you want to copy 'test' file to destination directory 'd' Use,
例如,如果您想将 'test' 文件复制到目标目录 'd' 使用,
mkcp test a/b/c/d
mkcpwill first check if destination directory exists or not, if not then make it and copy source file/directory.
mkcp将首先检查目标目录是否存在,如果不存在,则创建它并复制源文件/目录。
回答by developerprashant
Copy from source to an non existing path
从源复制到不存在的路径
mkdir –p /destination && cp –r /source/ $_
NOTE: this command copies all the files
注意:此命令复制所有文件
cp –r
for copying all folders and its content
cp –r
用于复制所有文件夹及其内容
$_
work as destination which is created in last command
$_
作为在最后一个命令中创建的目的地工作