2013-07-12 63 views
1

我想知道如何复制文件而不覆盖旧文件,我没有-n开关可用。BASH:如何在不覆盖旧文件的情况下复制文件

就我所知,cp -u和rsync都会覆盖较旧的文件,而且我不想要这种行为,我希望始终保留较旧的文件。

感谢

+0

如果它是一个选项,你可以写一个脚本来做到这一点。这是我首选的做事方法。通过这种方式,我可以对行为进行100%的定制 –

+0

您是否有可用的-b选项? – dougEfresh

+0

@RussellUhl,在编写脚本时要小心TOCTOU的风险。 –

回答

3

您可以使用“--interactive”选项(存在于我的cpGNU coreutils 6.12)覆盖前提示您,并用默认的填充:

echo 'n' | cp --interactive ~/somefile.txt ~/somefile_already_exists.txt 
+0

这个问题陈述了“一个文件”,但你是对的:'是n'是一个更一般的解决方案。 –

+0

nono .. echo'n'在这里确定+1。我的失败 – hek2mgl

+0

请注意,即使您使用'cp -ir a/* b /'(多个问题)'echo'n'|'也可以。 (已经测试过)我会预期echo'n'会压制第一个问题...将不得不调查这个 – hek2mgl

-3

这是一个非交互式做法。它检查文件是否存在(在初始附加一个随机数之后)。如果确实如此,它会寻找另一个随机数。这可以通过不同的方式进行修改。可以添加参数,等等。

copyfile() { 
     n=$RANDOM 
     while [ -f $1__$n ]  
     do 
     n=$RANDOM 
     done 
     cp $1 $1__$n 
    } 

用法:

copyfile file_to_copy 

您的文件将被命名为财产以后这样的:

Originalfile.txt_20625

所附的数字最有可能阻止覆盖的机会。如果这还不够,那么可以添加任何他们希望到文件末尾的东西,比如时间戳。如果你仍然担心这些措施后覆盖,那么你可能应该定期备份你的文件。

+0

删除字符?吉姆并不想删除,而是复制。 – dougEfresh

+0

为什么downvotes?这确实复制了一个文件。这个网站很荒谬。 –

+1

@BobBlogge,你仔细阅读过这个问题吗?如果'file_copy'已经存在,使用你的例子它将被覆盖。 –

1

将文件复制到同一目录中新创建的临时文件(请参阅在Linux下的mktemptempfile)。然后使用ln试图给出您想要的名称的副本。如果名称存在,则ln将失败;你可以尝试使用不同的名称,或只是发出错误信息,或其他。最后,删除临时名称。

+0

对不起,我希望避免复制文件(很大),谢谢。 –

+0

@JimMoyle:然后在执行上述操作之前测试文件是否存在。偶尔,你会得到一个毫无意义的副本,但上面列出的原子副本至少会阻止数据竞争。 – rici

相关问题