在Mac上使用cp命令的--parents选项

73

在Linux上,我可以使用cp命令的--parents选项,这样我就可以执行以下操作

cp --parents test/withintest/go.rb test2

http://www.gnu.org/software/coreutils/manual/html_node/cp-invocation.html

在 Mac 上,我没有这个选项可用。有没有办法在 Mac 上完成这个操作?为什么这个选项不可用?

PS. --parents 的作用如下:

'--parents' 每个目标文件的名称由将源文件的名称附加到目标目录和斜杠组成。

cp 命令中最后一个参数必须是现有目录的名称。

例如,命令:

      cp --parents a/b/c existing_dir 

将文件a/b/c复制到existing_dir/a/b/c,如果有任何缺失的中间目录,则创建它们。


4
安装它就行了 :) 与许多GNU实用程序一样,你可以从包管理器中安装它们,例如 brew install coreutils - flow2k
2
参考安装coreutils之后,您可以运行gcp --parents a/b/c existing_dir,因为coreutils会在MacOS已有版本的GNU命令前加上“g”。 - Chris Hayes
8个回答

100

这也让我感到很困扰。解决方法是使用rsync。

rsync -R test/withintest/go.rb test2

具有与cp --parents相同的效果,并且OS X标配rsync。


3
你知道为什么这个命令可能会在使用findxargs时失败吗?我尝试了find . -name "foo" | xargs rsync -R '{}' destination/ - AutonomousApps
rsync的缺点是它在许多发行版中默认未安装,通常是你想要避免使用的东西。 - undefined

17
你可以在Mac OS X上使用ditto命令:
基本形式
ditto <src-path> <dst-path>

做你想要的事情。还有很多其他选项-请查看手册页面


非常好。ditto some/dir/structure/file /tmp/some/dir/structure/file 可以创建/tmp下的some/dir/structure目录,这正是我们所期望的。 - ca2longoria
20
我不明白这如何回答原问题。 cp --parents a/b/c existing_dirditto a/b/c existing_dir似乎��了不同的事情。 - alecbz
1
@alecb 我认为这个答案是在回答OP实际想要实现的目标,而不是具体的方法。当我发现“ditto”命令时,我也经历了同样的思考过程。 - Echelon
6
原问题是复制一个文件并保留其路径层次结构。Ditto 可以复制整个目录树,但不能单独复制一个文件,因此这个答案是错误的。 - Moos
2
在跨平台的rsync可用时使用ditto是错误的。"ditto"答案不能被指定为正确答案。很抱歉这么严厉。 - KostaZ
@KostaZ 错误了。标题写着“mac”,所以这个答案是可行的。 - WestCoastProjects

7

您可以使用MacPorts安装GNU版本的cp

安装了MacPorts之后,您可以安装coreutils包:

sudo port install coreutils

接下来,您可以通过在命令前加上 g 来使用 GNU 版本的 cp 和其他核心实用程序(lsdatecat 等):

gcp --parents test/withintest/go.rb test2

如果您希望默认使用这些GNU版本,则可以将GNU二进制文件更新到您的路径中。请将以下内容添加到您的~/.bash_profile文件中:

export PATH="/opt/local/libexec/gnubin:$PATH"

4

Homebrew 方式:

安装 coreutils

brew install coreutils

使用以GNU为前缀的命令

gcp --parents test/withintest/go.rb test2

4
我使用了rsync命令,具体操作如下: rsync -R dir/**/file.json 目标文件夹路径

3

请尝试

mkdir -p `dirname "$file_path"` && cp "$old_dir/$file_path" "$file_path"

首先,在相对文件路径中创建具有所有中间目录的目录。然后将文件复制到新创建的目录。


0

我不会用GNU cp替换mac cp。我也不会使用ditto,因为它不跨平台。相反,使用跨平台工具,如rsync:

rsync <srcDir/srcFile> <dst>

结果:dst/srcDir/srcFile

这个对我来说不太起作用,rsync old/qtbase/src/plugins/platforms/xcb/xcb_qpa_lib.pro new 在 Mac 上给了我 new/xcb_qpa_lib.pro - tofutim
1
请参考Stephan的下面的答案,类似但适用于Mac。 - jaime

0
我不得不给rsync添加-dir选项才能让它对我起作用。
rsync -R -dir a/b tmp

结果:
$ find a
a
a/b
a/b/f1.txt
a/c
a/c/f2.txt
a/d
a/d/f3.txt

$ find tmp
tmp
tmp/a
tmp/a/b
tmp/a/b/f1.txt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接