You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让rsync在使用--no-relative时重命名目标目录中的重复文件?

解决rsync --no-relative下的同名文件重命名问题

rsync自带的-b --suffix确实只能处理目标目录已存在同名文件的情况,对于同一次传输中来自不同路径的同名文件,需要额外处理才能避免覆盖。以下是两种可行的方案:

方案一:预处理文件,添加路径前缀重命名

通过临时目录中转,给每个待传输文件添加来源路径的标识,再用rsync传输到目标目录,这样既保留了来源区分,又不会出现同名冲突。

以你的示例为例,执行以下脚本:

# 创建临时目录
temp_dir=$(mktemp -d)

# 遍历所有待传输文件,复制到临时目录时重命名
for file in sourceDir2/file.txt sourceDir3/file.txt; do
    # 将路径中的斜杠替换为下划线,生成新文件名
    new_name=$(echo "$file" | tr '/' '_')
    cp "$file" "$temp_dir/$new_name"
done

# 用rsync传输临时目录的文件到目标,同时保留-b选项处理目标已存在的文件
rsync --no-relative -b --suffix="_old" "$temp_dir"/* destDir

# 删除临时目录
rm -rf "$temp_dir"

这样传输后,目标目录会得到sourceDir2_file.txt和sourceDir3_file.txt,既不会互相覆盖,也会在目标已有同名文件时自动添加_old后缀备份。

方案二:自动添加递增后缀处理同名文件

如果不需要保留路径标识,只需要确保文件名唯一,可以用脚本检测临时目录中的文件名,重复时自动添加递增数字后缀:

temp_dir=$(mktemp -d)

for file in sourceDir2/file.txt sourceDir3/file.txt; do
    base_name=$(basename "$file")
    new_name="$base_name"
    counter=1
    # 检查临时目录中是否已存在同名文件,存在则递增后缀
    while [ -f "$temp_dir/$new_name" ]; do
        new_name="${base_name%.txt}_$counter.txt"
        counter=$((counter + 1))
    done
    cp "$file" "$temp_dir/$new_name"
done

rsync --no-relative -b --suffix="_old" "$temp_dir"/* destDir
rm -rf "$temp_dir"

执行后,目标目录会得到file.txt和file_1.txt(如果之前已经传输过sourceDir1的file.txt,那么这次的file.txt会被备份为file.txt_old,新的file.txt对应sourceDir2的文件,sourceDir3的文件则变为file_1.txt)。

补充说明

  • 如果你需要频繁执行这类操作,可以把上述脚本封装成一个函数,方便调用。
  • mktemp -d会创建安全的临时目录,避免权限问题和命名冲突。

内容的提问来源于stack exchange,提问作者Ray

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 17:24:47