Answers:
mv
无法合并或覆盖目录,即使使用此选项,也会失败并显示消息“ mv:无法将'a'移至'b':目录不为空”--force
。
您可以使用其他工具(例如rsync
,find
或什至cp
)解决此问题,但您需要仔细考虑其含义:
rsync
可以将一个目录的内容合并到另一个目录(理想情况下,使用--remove-source-files
1选项可以安全地仅删除已成功传输的源文件,-a
如果需要,可以使用通常的权限/所有权/时间保留选项)rsync
的--link-dest=DIR
选项(在可能的情况下创建硬链接而不是复制文件内容),并--remove-source-files
获得与regular非常相似的语义mv
。--link-dest
需要提供到源目录的绝对路径(或从目标到源的相对路径)。--link-dest
在非预期的方式(其可以或可以不引起并发症),需要知道(或确定)的绝对路径的源(作为参数--link-dest
),并再次离开一个空的目录结构被清理作为每1。find
用来顺序地在目标上重新创建源目录结构,然后分别移动实际文件cp
可以创建硬链接(简单地说,额外的指针指向同一个已存在的文件),它创建非常相似,合并的结果mv
(而且是非常IO-有效的,因为仅创建指针和没有实际数据必须被复制)这些变通办法中的哪一个(如果有)合适,将在很大程度上取决于您的特定用例。
与往常一样,请在执行任何这些命令之前先进行思考,然后进行备份。
1:请注意,rsync --remove-source-files
这不会删除任何目录,因此您将必须执行类似find -depth -type d -empty -delete
事后的操作才能摆脱空的源目录树。
mv
Debian是用于执行-重点是在尝试,因为联机帮助中没有提到这种行为...
--delete
仅删除目标目录中源目录中不存在的文件。
-H
函数保留硬链接,也可以使用硬链接目标文件--link-dest
。但是,在使用它们之前,请参见手册页。
rsync -av /source/ /destination/
(after checking)
rm -rf /source/
--remove-source-files
具有仅删除成功传输的文件的优点,因此您可以用于find
删除空目录,并且无需检查rsync
s的输出即可保留所有未传输的文件。
您可以使用cp命令的-l
选项,该选项在同一文件系统上创建文件的硬链接,而不是完整数据副本。以下命令将文件夹复制到已包含名称为的目录的父文件夹()。source/folder
destination
folder
cp -rl source/folder destination
rm -r source/folder
您可能还需要根据需要使用-P
(--no-dereference
--不要取消引用符号链接)或-a
(--archive
--保存所有元数据,还包括-P
选项)。
cp
不是rsync
因为每个系统都有cp
,每个人都有一个与之熟悉。
cp
的运行时间mv
。
-n
mv /fs1/file /fs2/
(跨文件系统)将执行复制,然后删除。
mv
可以“有效”(只要目标目录不存在)仍然有效,即使它不是“有效”或您所说的任何方法,cp -rl
也将失败。
我建议执行以下四个步骤:
cd ${SOURCE};
find . -type d -exec mkdir -p ${DEST}/\{} \;
find . -type f -exec mv \{} ${DEST}/\{} \;
find . -type d -empty -delete
或更妙的是,这是一个实现类似于mv
以下内容的语义的脚本:
#!/bin/bash
DEST="${@:${#@}}"
ABS_DEST="$(cd "$(dirname "$DEST")"; pwd)/$(basename "$DEST")"
for SRC in ${@:1:$((${#@} -1))}; do (
cd "$SRC";
find . -type d -exec mkdir -p "${ABS_DEST}"/\{} \;
find . -type f -exec mv \{} "${ABS_DEST}"/\{} \;
find . -type d -empty -delete
) done
rsync -u
(仅更新时才更新),mv
(至少在某些版本中)也可以-u
选择。但是,在那种情况下,您可能要删除非空源目录以及空目录,以涵盖源树中文件不是较新的情况。@schuess:如果需要,似乎可以有多个SOURCE参数。
这是合并目录的方法。它比rsync快得多,因为它只是重命名文件,而不是先复制文件然后删除它们。
cd source; find -type f -print0 | xargs -0 -n 1 -I {} mv '{}' 'dest/{}'
dest
已经是与in中同名的目录,则该命令将失败source
。文件将被移至dest
中的source
。该命令不超过罢了mv source/* source/dest/.
对于最纯粹的副本,我使用tar(-)B块读取副本方法。
例如,从源路径中(如果需要,在“ cd”中):
tar cBf - <sourcefolder> | (cd /your/target/folder ; tar xBf -)
这将创建源树的精确副本,其中所有者和权限保持不变。并且如果目标文件夹存在,则数据将被合并。仅已存在的文件将被覆盖。
例:
$ cd /data1/home
$ tar cBf - jdoe | (cd /data2/home ; tar xBf -)
复制操作成功后,您可以删除源(rm -rf <source>
)。当然,这并不是一个确切的举动:数据将被复制,直到您删除源为止。
作为选项,您可以使用-v来表示详细信息(在屏幕上显示要复制的文件): tar cBvf -
c
: 创造B
:读取完整块(用于管道读取)v
:详细f
:要写入的文件x
:提取-
:标准输出/标准输入sourcefolder
也可以*
(对于当前文件夹中的任何内容)
f -
通常不需要指定tar-默认值是从stdin / write读取到stdout。
这是一个对我有用的脚本。与rsync相比,我更喜欢mv,因此我使用Jewel和Jonathan Mayer的解决方案。
#!/bin/bash
# usage source1 .. sourceN dest
length=$(($#-1))
sources=${@:1:$length}
DEST=$(readlink -f ${!#})
for SRC in $sources; do
pushd $SRC;
find . -type d -exec mkdir -p ${DEST}/{} \;
find . -type f -exec mv {} ${DEST}/{} \;
find . -type d -empty -delete
popd
done
使用cp或rsync之类的命令不是一个好主意。对于大文件,将需要很长时间。mv更快,因为它只更新inode而不物理复制文件。更好的选择是使用操作系统的文件管理器。对于Opensuse,有一个名为Konquerer的文件管理器。它可以移动文件而无需实际复制它们。它具有Windows中的“剪切和粘贴”功能。只需选择目录A中的所有子目录。右键单击并“移入”目录B,其中可能包含具有相同名称的子目录。它将合并它们。您还可以选择是否要覆盖或重命名具有相同名称的文件。
mv
使用时会发生什么情况。
Python解决方案
由于找不到满意的预先存在的解决方案,因此我决定制作一个快速的Python脚本来实现它。
特别地,该方法是有效的,因为它仅在自下而上时遍历源文件树。
它还将允许您根据自己的喜好快速调整文件覆盖处理之类的内容。
用法:
move-merge-dirs src/ dest/
将移动的所有内容src/*
到dest/
和src/
会消失。
移动合并目录
#!/usr/bin/env python3
import argparse
import os
def move_merge_dirs(source_root, dest_root):
for path, dirs, files in os.walk(source_root, topdown=False):
dest_dir = os.path.join(
dest_root,
os.path.relpath(path, source_root)
)
if not os.path.exists(dest_dir):
os.makedirs(dest_dir)
for filename in files:
os.rename(
os.path.join(path, filename),
os.path.join(dest_dir, filename)
)
for dirname in dirs:
os.rmdir(os.path.join(path, dirname))
os.rmdir(source_root)
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='Move merge src/* into dest. Overwrite existing files.'
)
parser.add_argument('src_dir')
parser.add_argument('dest_dir')
args = parser.parse_args()
move_merge_dirs(args.src_dir, args.dest_dir)
另请参阅:https : //stackoverflow.com/questions/22588225/how-do-you-merge-two-directories-or-move-with-replace-from-the-windows-command
这是用于将文件和文件夹移动到其他目标的命令:
$ mv /source/path/folder /target/destination/
切记:mv
如果该文件夹是b̲e̲i̲n̲g m̲e̲r̲ge̲d̲(即,目的地中已经存在另一个具有相同名称的文件夹)并且d̲e̲s̲t̲i̲n̲a̲t̲i̲o̲n̲ o̲n̲e̲ i̲s̲n̲o̲t̲ e̲m̲pt̲y,则该命令将不起作用。
mv:无法将“ /源/路径/文件夹”移动到“ /目标/目标/文件夹”:目录不为空
如果目标文件夹为空,则以上命令将正常运行。
因此,为了在任何情况下都可以合并两个文件夹,
请使用以下两个命令之一:
$ cp -rf /source/path/folder /target/destination/
$ rm -rf /source/path/folder
或将两者结合为一次性命令:
$ cp -rf /source/path/folder /target/destination/ && rm -rf /source/path/folder
mv =移动
cp =复制
rm =删除-r用于目录(文件夹)
-f强制执行
mv
。有了更广泛的真理,这个答案会更好。Linux,BSD和“真实” Unix,或POSIX或SUS的参考。