Linux:复制并创build目标目录,如果它不存在
我想要一个命令(或者可能是cp的一个选项)创build目标目录,如果它不存在。
例:
cp -? file /path/to/copy/file/to/is/very/deep/there  test -d "$d" || mkdir -p "$d" && cp file "$d" 
  (对于cp没有这个选项)。 
如果以下两者都是正确的:
-  您正在使用cp的GNU版本(而不是,例如,Mac版本)和
- 你正在复制一些现有的目录结构,你只需要重新创build它
 那么你可以用cp的--parents标志来做到这一点。 从信息页面(可在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.
例:
 /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 
这样一个老问题,但也许我可以提出一个替代解决scheme。
 您可以使用install程序来复制您的文件并“即时”创build目标path。 
 install -D file /path/to/copy/file/to/is/very/deep/there/file 
但是有一些方面需要考虑,
- 您还需要指定目标文件名称 ,而不仅仅是目标path
- 目标文件将是可执行的 (至less,据我看到我的testing)
 通过添加-m选项来设置目标文件的权限(例如: -m 664将创build具有权限rw-rw-r--的目标文件,就像通过touch创build新文件一样),可以轻松修改#2。 。 
这里是我被启发的答案的无耻链接 =)
简答
 要将myfile.txt复制到/foo/bar/myfile.txt ,请使用: 
 mkdir -p /foo/bar && cp myfile.txt $_ 
这个怎么用?
这里有几个组件,所以我将逐步介绍所有的语法。
  在POSIX标准中指定的mkdir实用程序生成目录。  -p参数,根据文档,将导致mkdir 
创build任何缺less的中间path名组件
 这意味着当调用mkdir -p /foo/bar ,如果/foo不存在, mkdir将创build/foo 和 /foo/bar 。  (没有-p ,它会抛出一个错误。 
 在POSIX标准 (或Bash手册,如果您愿意的话)中logging的&&列表操作符具有如下效果:如果mkdir -p /foo/bar成功执行,则仅执行cp myfile.txt $_ 。 这意味着如果mkdir失败, cp命令将不会尝试执行,原因很多,可能会失败 。 
 最后,作为cp的第二个parameter passing的$_是一个“特殊参数”,它可以方便地避免重复长参数(如文件path),而不必将它们存储在variables中。 根据Bash手册 ,它: 
扩展到上一个命令的最后一个参数
 在这种情况下,这就是我们传递给mkdir的/foo/bar 。 因此, cp命令扩展为cp myfile.txt /foo/bar ,它将myfile.txt复制到新创build的/foo/bar目录中。 
 请注意, $_ 不是 POSIX标准的一部分 ,因此理论上Unix变体可能有一个不支持这种结构的shell。 但是,我不知道任何现代的炮弹不支持$_ ; 当然Bash,Dash和zsh都可以。 
 最后一点:我在这个答案开始时给出的命令假设你的目录名没有空格。如果你用空格处理名字,你需要引用它们,以便不同的单词不被视为mkdir或cp不同参数。 所以你的命令实际上是这样的: 
 mkdir -p "/my directory/name with/spaces" && cp "my filename with spaces.txt" "$_" 
Shell函数根据需要调用它,将其称为“埋藏”副本,因为它为该文件挖掘出一个空洞:
 bury_copy() { mkdir -p `dirname $2` && cp "$1" "$2"; } 
以下是一种方法:
 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会给你的目的地目录或文件的父。  mkdir -p`dirname …`然后创build该目录,确保当你调用cp -r时,正确的基目录就位。 
这种超级父母的优点是,它适用于目的地path中的最后一个元素是文件名的情况。
它将在OS X上工作。
 install -D file -m 644 -t /path/to/copy/file/to/is/very/deep/there 
  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的答案适用于
 cp SOURCE DEST 
  cp风格,但是如果你使用的是错误的东西 
 cp SOURCE... DEST/ 
  cp风格。 
 我认为在这种用法(即目标目录尚不存在的情况下)中,“DEST”是不明确的,这也许是为什么cp从未为此添加过一个选项。 
所以这里是我的这个函数的版本,它在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 } 
只需在你的.bashrc中添加以下内容,如果你需要的话。 在Ubuntu中工作。
 mkcp() { test -d "$2" || mkdir -p "$2" cp -r "$1" "$2" } 
例如,如果您想将“testing”文件复制到目标目录“d”使用,
 mkcp test a/b/c/d 
mkcp将首先检查目标目录是否存在,如果不存在,则复制源文件/目录。
从源复制到不存在的path
mkdir -p / destination && cp -r / source / $ _
注意:这个命令复制所有的文件
cp -r复制所有文件夹及其内容
$ _作为在上一个命令中创build的目的地
与我所有的尊重上面的答案,我更喜欢使用rsync如下:
 $ rsync -a directory_name /path_where_to_inject_your_directory/ 
例:
 $ rsync -a test /usr/local/lib/ 
 rsync file /path/to/copy/file/to/is/very/deep/there 
你走了,没有问题问。
假设你正在做类似的事情
cp file1.txt A / B / C / D / file.txt
A / B / C / D是不存在的目录
一个可能的解决scheme如下
 DIR=$(dirname A/B/C/D/file.txt) # DIR= "A/B/C/D" mkdir -p $DIR cp file1.txt A/B/C/D/file.txt 
希望有所帮助!