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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 17:46:05  来源:igfitidea点击:

Linux: copy and create destination dir if it does not exist

linuxbashshellunixcp

提问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:

如果以下两种情况都为真:

  1. You are using the GNU version of cp(and not, for instance, the Mac version), and
  2. You are copying from some existing directory structure and you just need it recreated
  1. 您使用的是 GNU 版本cp(而不是,例如 Mac 版本),并且
  2. 您正在从一些现有的目录结构复制,您只需要重新创建它

then you can do this with the --parentsflag of cp. From the info page (viewable at http://www.gnu.org/software/coreutils/manual/html_node/cp-invocation.html#cp-invocationor with info cpor 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

dirnamewill 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 installprogramme 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:

但是,有一些方面需要考虑:

  1. you need to specify also the destination file name, not only the destination path
  2. the destination file will be executable(at least, as far as I saw from my tests)
  1. 您还需要指定目标文件名,而不仅仅是目标路径
  2. 目标文件将是可执行的(至少,就我从测试中看到的而言)

You can easily amend the #2 by adding the -moption to set permissions on the destination file (example: -m 664will 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.txtto /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 -pargument, 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 /fooand/foo/barif /foodoesn't already exist. (Without -p, it will instead throw an error.

这意味着在调用时mkdir -p /foo/barmkdir将创建/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/barexecutes successfully. This means the cpcommand won't try to execute if mkdirfails 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 cpis 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/barwe passed to mkdir. So the cpcommand expands to cp myfile.txt /foo/bar, which copies myfile.txtinto the newly created /foo/bardirectory.

在这种情况下,这就是/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 mkdiror 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

cphas 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 cphas 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 –rfor copying all folders and its content

cp –r用于复制所有文件夹及其内容

$_work as destination which is created in last command

$_作为在最后一个命令中创建的目的地工作