我需要一个命令(可能是cp的一个选项)来创建目标目录(如果目标目录不存在)。
例子:
cp -? file /path/to/copy/file/to/is/very/deep/there
我需要一个命令(可能是cp的一个选项)来创建目标目录(如果目标目录不存在)。
例子:
cp -? file /path/to/copy/file/to/is/very/deep/there
当前回答
简短的回答
复制myfile.txt到/foo/bar/myfile.txt,使用:
mkdir -p /foo/bar && cp myfile.txt $_
这是如何工作的呢?
这里有几个组件,所以我将一步一步地介绍所有语法。
POSIX标准中指定的mkdir实用程序创建目录。根据文档,-p参数将导致mkdir
创建任何缺少的中间路径名组件
这意味着当调用mkdir -p /foo/bar时,如果/foo不存在,mkdir将创建/foo和/foo/bar。(如果没有-p,它将抛出一个错误。
&&列表操作符,如POSIX标准(或Bash手册,如果你喜欢)中所述,其效果是只有在mkdir -p /foo/bar成功执行时才执行cp myfile.txt $_。这意味着如果mkdir失败,cp命令将不会尝试执行,原因有很多。
最后,我们传递给cp的第二个参数$_是一个“特殊参数”,可以方便地避免重复长参数(如文件路径),而不必将它们存储在变量中。根据Bash手册,它:
展开到上一个命令的最后一个参数
在本例中,这是我们传递给mkdir的/foo/bar。因此cp命令展开为cp myfile.txt /foo/bar,将myfile.txt复制到新创建的/foo/bar目录中。
注意$_不是POSIX标准的一部分,所以理论上Unix变体可能有一个不支持这个构造的shell。然而,我不知道任何现代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"; }
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 SOURCE... DIRECTORY/
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
}
这对我来说很有用
cp -vaR ./from ./to
mkdir -p "$d" && cp file "$d"
(cp没有这样的选项)。
正如上面help_asap和sponge所建议的,你可以使用'install'命令将文件复制到现有目录中,或者如果目标目录不存在,则创建新的目标目录。
选项1 安装-D filename some/deep/directory/filename 将文件复制到新的或现有目录,并赋予文件名默认的755权限
选项2 安装-D filename -m640 some/deep/directory/filename 按照选项1,但给文件名640权限。
选项3 安装-D filename -m640 -t some/deep/directory/ 根据选项2,但目标文件名到目标目录,所以文件名不需要写在源和目标。
选项4 install -D filena* -m640 -t some/deep/directory/ 与选项3相同,但对多个文件使用通配符。
它在Ubuntu中工作得很好,将两个步骤(创建目录和复制文件)合并为一个步骤。