首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >比较两个目录树以创建文件/文件夹级修补程序(包括二进制文件)

比较两个目录树以创建文件/文件夹级修补程序(包括二进制文件)
EN

Stack Overflow用户
提问于 2011-09-22 07:52:46
回答 3查看 7.1K关注 0票数 6

有很多为文本文件创建文件级补丁的解决方案。我正在寻找的是一个简单的脚本/shell命令,它将比较oldversion/ newversion/,并给我一个文件树,我需要复制旧版本以使其与新版本相同(假设文件在更新版本中未被删除)。请注意,这两个文件夹同时包含二进制文件和文本文件。

之前,我们使用的是黑客:

fdupes -qrf newversion/ oldversion/ | grep "newversion" | xargs rm;

给我们留下了可以打包成补丁的文件夹"newversion“。

不幸的是,这被证明是灾难性的,因为fdupes不考虑文件名。

最棒的是像fdupes这样的东西,它实际上在比较中包含了文件名。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-09-22 08:10:28

可以要求diff命令输出不同的文件名。

代码语言:javascript
复制
diff --quiet --recurse --unidirectional-new-file OLDDIR NEWDIR

Files old/main and new/main differ
Files old/main.cpp and new/main.cpp differ
Files old/Makefile and new/Makefile differ
Files old/sounds/popalien.wav and new/sounds/popalien.wav differ
Files old/sounds/saucer.wav and new/sounds/saucer.wav differ

当然,这并不是一个很好的输出,但是因为您只是在寻找要打包为补丁的新文件,所以一个快速的sed管道会产生奇妙的效果:

代码语言:javascript
复制
diff --quiet --recurse -unidirectional-new-file OLDDIR NEWDIR | \
  sed "s/^.* and \(.*\) differ/\1/"

(为可读性而中断)

代码语言:javascript
复制
new/main
new/main.cpp
new/Makefile
new/sounds/popalien.wav
new/sounds/saucer.wav

' and‘周围的空格和前面的'differ’不同

要比较的操作数的顺序会有所不同,第一个参数是‘and’的左边,第二个是后面的。注意这一点。

此外,如果您从NEWDIR中删除文件,系统将不会找到给定的文件,只能找到已添加或更改的文件。要同时输出在这两个子目录中都找不到的文件的文件名,请将--unidirection new-file替换为--new-file。(除--单向..外,所有选项均为短选项。)

票数 5
EN

Stack Overflow用户

发布于 2011-09-22 08:08:51

diff -ruN oldversion newversion

票数 1
EN

Stack Overflow用户

发布于 2016-01-14 15:16:53

我知道已经很久了。我需要同样的解决方案。我找到了这篇文章,但这还不够。然后我发现,如果你patch相同的副本,rsync可以做这项工作,并且不需要与其他更改合并。我打算将其用于更新断开连接的机器上的yum镜像。我的完整解决方案有点复杂,我从内存中编写命令,所以一些细节可能是错误的,但在核心:

代码语言:javascript
复制
# create identical copy "copy.0"
rsync -a master/ copy.0/

# Presumably transfer copy.0/ to another machine for offline use
# but copy.0 must not mutate outside of this process or sync probably
# will not work.

# some time later update master, e.g. rsync master from upstream mirror
# mutates master in some way, changes/adds/removes remove files including
# binaries
echo -n $'\001\002' > master/new.bin
rm master/gone.bin

# generate rsync batch that can be used to ``patch`` copy.0
# to become identical to master
rsync -a --delete --itemize-changes --only-write-batch=copy.0.batch \
    master/ copy.0/
# now the file copy.0.batch contains only the deltas to be applied

# transfer the batch file to where it needs to be applied

# apply the batch to copy.0
rsync -a --delete --itemize-changes --read-batch=copy.0.batch copy.0/

这会处理删除和许多其他事情,可能是权限,时间戳等,但我认为它可能不会将硬链接作为硬链接处理,并且可能会将它们创建为单独的未链接文件。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7508035

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档