Linux如何复制但不覆盖?


Answers:


589

摘自手册页

-n, --no-clobber
              do not overwrite an existing file (overrides a previous -i option)

例:

cp -n myoldfile.txt mycopiedfile.txt

32
请注意,如果文件存在,将退出并显示错误消息。要成功退出,请尝试 cp -n source.txt destination.txt || true
galenandrew '16

13
cp -n如果文件在Ubuntu 12.04上存在,则@galenandrew 不会错误退出。
2016年

@galenandrew确认。谢谢。将运行脚本添加到目标后,我的项目不在Xcode中构建。
鲁伊斯

@AaronFranke看起来像。
鲍里斯(Boris)

93

考虑使用rsync

rsync -a -v --ignore-existing src dst

按照评论rsync -a -v src dst是不正确的,因为它将更新现有文件。


7
您想要添加--ignore-existing标志以防止现有文件被覆盖。
所有工人都是必不可少的

7
完整的命令rsync -a -v --ignore-existing <src> <dst>确实是正确的答案,而不是cp -u上面的答案。
白鸟2015年

如果先前的副本被打断并且仅复制了一个截断的文件,我确定cp -u不会重新复制它...但是会使用--ignore-existing进行rsync吗?可能两者都不是...所以使它们完全等效,对吧?
dagelf

rsync保留文件时间戳记,而cp使用当前时间(以我的经验)
Stefan Diabo

1
有些服务器没有rsync
mebada


33

这将适用于RedHat:

false | cp -i source destination 2>/dev/null

更新不是覆盖是不同的。


4
false在这里做什么?
Frozen Flame》 2014年

11
@FrozenFlame回答-i问题。
ceving

显然,如果您尝试复制多个ARG_MAX文件,则此命令将无效。要解决这种情况,请检查此链接
mginius

2
同样明显的是,如果地球撞向太阳,此命令将无效。

32

对于发现没有'n'选项的人(例如RedHat上的我),您可以使用 cp -u仅在源比现有源(或不存在现有源)新的情况下写文件。

[edit]如评论中所述,这将覆盖较旧的文件,所以这并不是OP想要的。为此,请使用ceving的答案。


11
OP要求不要覆盖现有文件,即使这些文件早于复制的文件-u也实际上不适合其用途。
安德鲁·洛特

4
天哪,你是绝对正确的。我很惊讶花了这么长时间才注意到。
Grim ...

可能不是OP要求的,但这恰恰是我为Uberspace(Centos 7)所需的。谢谢!
Thomas Praxl

六年前,我很高兴能为您提供帮助:-D
Grim ...

10

Alpine linux:下面的答案仅适用于单个文件:在alpine中cp -n不起作用(false | cp -i ...也是),因此在我发现的情况下有效的解决方案是:

if [ ! -f env.js ]; then cp env.example.js env.js; fi 

在上面的示例中,如果env.js文件不存在,那么我们将复制env.example.jsenv.js


1

某些版本的cp没有--no-clobber选项。在这种情况下:

  echo n | cp -vipr src/* dst
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.