fly*_*ire 306 unix linux bash shell cp
我想要一个命令(或者可能是cp的一个选项),如果它不存在,则创建目标目录.
例:
cp -? file /path/to/copy/file/to/is/very/deep/there
Run Code Online (Sandbox Code Playgroud)
Mic*_*ker 276
mkdir -p "$d" && cp file "$d"
Run Code Online (Sandbox Code Playgroud)
(没有这样的选择cp).
Pau*_*ipp 223
如果满足以下两个条件:
cp(而不是Mac版本),以及然后你可以用--parents旗帜做到这一点cp.从信息页面(可在http://www.gnu.org/software/coreutils/manual/html_node/cp-invocation.html#cp-invocation或用info cp或查看man cp):
Run Code Online (Sandbox Code Playgroud)--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
Run Code Online (Sandbox Code Playgroud)
Mar*_*ery 55
要复制myfile.txt到/foo/bar/myfile.txt,请使用:
mkdir -p /foo/bar && cp myfile.txt $_
Run Code Online (Sandbox Code Playgroud)
这有几个组件,所以我将逐步介绍所有语法.
该MKDIR工具,如POSIX标准规定,使得目录.的-p说法,每文档,会造成MKDIR到
创建任何缺少的中间路径名组件
意思是在调用时mkdir -p /foo/bar,mkdir将创建/foo , /foo/bar如果/foo还没有存在.(没有-p,它会抛出错误.
该&&列表操作,如记录在POSIX标准(或猛砸手动,如果你喜欢),有效果cp myfile.txt $_,如果只得到执行mkdir -p /foo/bar成功执行.这意味着cp如果由于mkdir失败的原因之一而失败,则命令将不会尝试执行.
最后,$_作为第二个参数传递的cp是一个"特殊参数",它可以方便地避免重复长参数(如文件路径),而不必将它们存储在变量中.根据Bash手册,它:
扩展到上一个命令的最后一个参数
在这种情况下,/foo/bar我们传递给了mkdir.因此cp命令扩展为cp myfile.txt /foo/bar,复制myfile.txt到新创建的/foo/bar目录中.
请注意,$_是不是 POSIX标准的一部分,所以理论上Unix的变种可能具有不支持此构建物的外壳.但是,我不知道任何不支持的现代炮弹$_; 当然Bash,Dash和zsh都这样做.
最后一点:我在本回答开头给出的命令假设您的目录名称没有空格.如果您要处理带空格的名称,您需要引用它们以便使用不同的单词不被视为mkdir或的不同参数cp.所以你的命令实际上看起来像:
mkdir -p "/my directory/name with/spaces" && cp "my filename with spaces.txt" "$_"
Run Code Online (Sandbox Code Playgroud)
hel*_*sap 35
这么老的问题,但也许我可以提出一个替代解决方案.
您可以使用该install程序复制文件并"动态"创建目标路径.
install -D file /path/to/copy/file/to/is/very/deep/there/file
Run Code Online (Sandbox Code Playgroud)
但是,有一些方面需要考虑:
您可以通过添加-m用于设置目标文件权限的选项轻松修改#2 (例如:-m 664将创建具有权限的目标文件rw-rw-r--,就像创建新文件一样touch).
And*_*oss 17
Shell函数可以执行您想要的操作,将其称为"埋葬"副本,因为它为文件挖掘了一个漏洞:
bury_copy() { mkdir -p `dirname $2` && cp "$1" "$2"; }
Run Code Online (Sandbox Code Playgroud)
Jam*_*dle 10
这是一种方法:
mkdir -p `dirname /path/to/copy/file/to/is/very/deep/there` \
&& cp -r file /path/to/copy/file/to/is/very/deep/there
Run Code Online (Sandbox Code Playgroud)
dirname将为您提供目标目录或文件的父级.然后mkdir -p`dirname ...`将创建该目录,确保在调用cp -r时,正确的基本目录就位.
这种过度父母的优点是它适用于目标路径中的最后一个元素是文件名的情况.
它将适用于OS X.
小智 9
这已经很晚了,但它可能会在某个地方对新手有所帮助。如果您需要自动创建文件夹rsync应该是您最好的朋友。
rsync /path/to/sourcefile /path/to/tragetdir/thatdoestexist/
Run Code Online (Sandbox Code Playgroud)
正如上面 help_asap 和 Spongeman 所建议的,您可以使用“install”命令将文件复制到现有目录,或者创建新的目标目录(如果它们尚不存在)。
选项 1
install -D filename some/deep/directory/filename
将文件复制到新的或现有的目录并赋予文件名默认 755 权限
选项 2
install -D filename -m640 some/deep/directory/filename
与选项 1 相同,但提供文件名 640 权限。
选项 3
install -D filename -m640 -t some/deep/directory/
与选项 2 相同,但将文件名定位到目标目录中,因此不需要在源和目标中都写入文件名。
选项 4
install -D filena* -m640 -t some/deep/directory/
与选项 3 相同,但对多个文件使用通配符。
它在 Ubuntu 中运行良好,并将两个步骤(目录创建然后文件复制)合并为一个步骤。
只需在 .bashrc 中添加以下内容,并根据需要进行调整。在 Ubuntu 中工作。
mkcp() {
test -d "$2" || mkdir -p "$2"
cp -r "$1" "$2"
}
Run Code Online (Sandbox Code Playgroud)
例如,如果您想将“test”文件复制到目标目录“d”,请使用,
mkcp test a/b/c/d
Run Code Online (Sandbox Code Playgroud)
mkcp将首先检查目标目录是否存在,如果不存在则创建它并复制源文件/目录。
install -D file -m 644 -t /path/to/copy/file/to/is/very/deep/there
小智 6
只是为了恢复并在一行中提供完整的工作解决方案。如果您想重命名文件,请小心,您应该包含一种为 mkdir 提供干净的目录路径的方法。$fdst 可以是文件或目录。下一个代码应该在任何情况下都有效。
fsrc=/tmp/myfile.unk
fdst=/tmp/dir1/dir2/dir3/myfile.txt
mkdir -p $(dirname ${fdst}) && cp -p ${fsrc} ${fdst}
Run Code Online (Sandbox Code Playgroud)
或 bash 特定
fsrc=/tmp/myfile.unk
fdst=/tmp/dir1/dir2/dir3/myfile.txt
mkdir -p ${fdst%/*} && cp -p ${fsrc} ${fdst}
Run Code Online (Sandbox Code Playgroud)
小智 6
无需创建脚本并使用简单的命令...
mkdir -p /destination-folder/ && cp file-name /destination-folder/
Run Code Online (Sandbox Code Playgroud)
考虑到以上所有答案,我更喜欢按以下方式使用rsync:
$ rsync -a directory_name /path_where_to_inject_your_directory/
Run Code Online (Sandbox Code Playgroud)
例:
$ rsync -a test /usr/local/lib/
Run Code Online (Sandbox Code Playgroud)