以下面的目录树为例,将directory/folderA的内容移动到目录的最佳方法是什么?
如果目标文件中存在同名文件,例如: directory/folderA/2017/06/info.log和directory/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将使用cp和rm来完成移动,但是仍然首先移除目标,复制硬链接文件( -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