Linux下实现两文件夹合并:更新文件不覆盖(类Git Merge方式)
嘿,这个需求完全可以用Linux下的工具组合来实现,不用手动挨个文件处理!我给你梳理下具体的操作步骤,分两部分搞定:新文件同步和现有文件的增量合并(完全贴合你要的Git Merge式追加效果)。
用rsync就能轻松搞定,它会自动识别provided里新增的文件,只复制到done,不会碰done里已经存在的文件(避免覆盖你之前的修改)。执行这条命令:
rsync -av --ignore-existing provided/ done/
参数说明:
-a:归档模式,保留文件权限、时间戳等所有元数据,保证复制的文件和原文件一致-v:verbose模式,显示同步过程,能清楚看到哪些新文件被复制--ignore-existing:核心参数,跳过done中已存在的文件,只同步provided里的新增文件
这里用Git自带的git merge-file工具最合适,它支持三方合并——正好匹配你的场景:初始的provided(你最开始复制给done的版本)、你修改后的done、更新后的provided。它会自动把provided里新增的内容合并到done,同时保留你之前的修改,有冲突的话也会像Git一样标记出来。
前提:你得保留初始的provided版本
如果当初复制done之后,你没删掉原始的provided(或者有备份,比如叫provided_initial),那直接用这个脚本批量处理:
# 遍历provided里的所有文件 for file in $(cd provided && find . -type f); do # 只处理done和初始版本都存在的文件 if [ -f "done/$file" ] && [ -f "provided_initial/$file" ]; then echo "正在合并文件:$file" git merge-file "done/$file" "provided_initial/$file" "provided/$file" fi done
这条命令会逐个处理每个共同文件,把provided相对于初始版本的新增内容合并到done里。
如果没有初始版本备份怎么办?
如果原始的provided已经被覆盖了,那可以用diff生成provided和done的差异,然后只提取新增的行追加到done,但这种方式没法处理冲突(比如你和provided都修改了同一行),只能作为临时方案:
for file in $(cd provided && find . -type f); do if [ -f "done/$file" ]; then # 生成provided比done多的行,追加到done文件末尾 diff -u done/$file provided/$file | grep -E '^\+' | grep -v '^+++' >> done/$file fi done
⚠️ 注意:这个方法很粗糙,只适合完全没有冲突的场景,优先用前面的git merge-file方案!
如果git merge-file遇到冲突(比如你和provided都修改了同一行内容),它会在done的文件里插入类似Git的冲突标记:
<<<<<<< done/[filename] 你在done里的修改内容 ======= provided里新增的内容 >>>>>>> provided/[filename]
你只需要手动编辑这些标记,保留需要的内容,删除标记即可。
内容的提问来源于stack exchange,提问作者Myhrael

