如何执行相当于yes |的mv 目录上的cp -rf?

以下面的目录树为例,将directory/folderA的内容移动到目录的最佳方法是什么?

如果目标文件中存在同名文件,例如: directory/folderA/2017/06/info.logdirectory/2017/06/info.log directory/folderA/2017/06/info.log ,如何覆盖文件。

 directory |-- folderA | |-- 2017 | | |-- 06 | | | |-- 2016 | | |-- 12 | | |-- 11 | | |-- 10 | |-- 2017 | |-- 04 | |-- 05 | |-- 06 | |-- 2016 | | 

你可以用cp -l来实现这个function( – 链接,而不是复制 ):

 cp -rfl folderA . rm -rf folderA 

mv只是移动即重命名目录为您的directory 。 为了在同一文件系统中移动文件, mv使用rename()系统调用。 如果源和目标在不同的文件系统上, mv将使用cprm来完成移动,但是仍然首先移除目标,复制硬链接文件( -R ),但不遵循符号链接( -P ):

 rm -f destination_path && \ cp -pRP source_file destination && \ rm -rf source_file 

虽然你不能改变mv这种行为,但cp命令本身更加灵活,你应该使用它。 使用cp-f会导致在目标中删除和创build单个文件,而不是首先删除整个目标。

cp也是有限的,因为它只能覆盖( -f ),保存者( -n )或者问( -i )。 如果您在决定保留哪个文件之前需要比较文件,则需要使用rsync

如果你仍然需要使用rename()系统调用,但是完成目标合并的目标,你需要编写一个脚本来调用单个文件的rename()

首先,我创build了你的目录树

 [root@localhost /tmp]# mkdir -pv directory/folderA/2017/06 directory/folderA/2016/{10..12} directory/2017/{04..06} directory/2016 

然后我创build你的示例文件:

 [root@localhost /tmp]# touch directory/{,folderA}/2017/06/info.log 

最后,我使用rsync和–delete-after来移动,而不是rsync的默认行为,它会创build一个副本:

 [root@localhost /tmp]# rsync --delete-after -a directory/folderA/ directory 

注意:如果您希望复制目录后删除目录,则需要在源目录(即目录/ folderA /而不是目录/ folderA)之后的尾部“/”。

当然,如果你真的想inputmv来获得所需的行为,你可以创build一个自定义的shell函数。 我不是主张这个,但是这是可能的。 马虎,但可能。

这里有一个你可以添加到你的〜/ .bashrc中的自定义函数:

 function mv() { if [[ "$@" =~ .*--delete-after.*-av*.* ]]; then rsync $@ else command mv $@ fi; } 

然后通过注销并重新login来调用已更新的〜/ .bashrc,或者键入:

 [root@localhost /tmp]# exec bash 

现在您可以使用以下两种方法testing自定义函数

 [root@localhost /tmp]# mv --delete-after -av directory/folderA/ directory 

得到详细的输出,

或与:

 [root@localhost /tmp]# mv --delete-after -a directory/folderA/ directory 

只有遇到任何错误才能接收错误。

顺便说一句,你也可以通过发出你的cp命令来避免在cp -rf命令中inputyes。

 [root@localhost /tmp]# \cp -rf directory/folderA/* directory/ 

你滚出来的原因是你可能在你的〜/ .bashrc中有一个cp命令的别名,例如:

 [root@localhost /tmp]# alias cp='cp -i' 

您可以通过键入来validation:

 [root@localhost /tmp]# type cp