如何移动合并含大量文件的目录(仅替换文件不替换文件夹)
批量移动合并大量文件的解决方案
问题背景
我有两个目录结构如下:
root_a - dir_b -- file -- file -- ... - dir_c -- file -- file -- ... root_b - dir_b -- file -- file -- ... - dir_c -- file -- file -- ...
每个子目录(如dir_b、dir_c)包含数万个文件。需要将root_a和root_b的内容合并移动到目标目录root_c,最终结构如下:
root_c - dir_b -- file (来自root_a/dir_b) -- file (来自root_b/dir_b) -- ... - dir_c -- file (来自root_a/dir_c) -- file (来自root_b/dir_c) -- ...
尝试用Bash的mv命令实现时,因文件数量过多触发argument list too long错误,原脚本如下:
#!/bin/bash # check if the number of arguments is correct if [ $# -ne 2 ]; then echo "Usage: $0 SOURCE TARGET" exit 1 fi # set variables for the source and target directories src=$1 tgt=$2 # move all directories and files from the source to the target, replacing any existing files mv -f $src/* $tgt
核心要求:必须执行移动操作,不能复制后删除——存储空间有限,且复制耗时太长。
解决方法:避免通配符展开导致参数过多
原脚本失败的根源是$src/*会被Shell展开成所有文件的完整路径,当文件数量过万时,超出系统允许的命令行参数长度限制。以下是两种可行的解决方案:
方法1:用find逐个移动文件
通过find遍历文件并逐个执行mv,从根本上避免参数过多问题:
#!/bin/bash # 定义单个源目录到目标目录的合并移动逻辑 merge_move() { local src_dir=$1 local tgt_dir=$2 # 遍历源目录下的所有子目录 for subdir in "$src_dir"/*/; do # 提取子目录名称(如dir_b) subdir_name=$(basename "$subdir") # 确保目标子目录存在(不存在则创建) mkdir -p "$tgt_dir/$subdir_name" # 遍历子目录下的所有文件,逐个移动 find "$subdir" -maxdepth 1 -type f -exec mv -f {} "$tgt_dir/$subdir_name/" \; # 移动完成后删除空的源子目录(可选,按需启用) rmdir "$subdir" done } # 检查参数是否符合要求(两个源目录 + 一个目标目录) if [ $# -ne 3 ]; then echo "Usage: $0 SOURCE_A SOURCE_B TARGET" exit 1 fi src_a=$1 src_b=$2 tgt=$3 # 依次处理两个源目录 merge_move "$src_a" "$tgt" merge_move "$src_b" "$tgt"
maxdepth 1:确保只处理子目录下的直接文件,不递归更深层级mv -f:强制覆盖目标目录中的同名文件(若需保留重复文件,可修改为带前缀的重命名,比如mv {} "$tgt_dir/$subdir_name/$(basename {})_from_$(basename "$src_dir")")
方法2:用rsync高效移动文件
rsync支持直接"搬家"式移动,处理大量文件时效率更高,还能自动维护目录结构:
# 移动root_a的内容到root_c,完成后删除源文件 rsync -av --remove-source-files "root_a/" "root_c/" # 移动root_b的内容到root_c,完成后删除源文件 rsync -av --remove-source-files "root_b/" "root_c/" # 清理空的源目录 rmdir "root_a"/* "root_b"/* rmdir "root_a" "root_b"
参数说明:
-a:归档模式,保留文件权限、时间戳等属性,并递归处理目录-v:显示详细移动过程(可选,可去掉以静默执行)--remove-source-files:仅删除被成功移动的文件,空目录需手动清理
内容的提问来源于stack exchange,提问作者pookie
相关产品推荐
相关产品推荐

