用于排序唯一文件的简单 diff/patch 脚本

Simple diff/patch script for sorted unique file

我怎么能写一个简单的 diff resp。用于将添加和删除应用到文件中的行列表的补丁脚本?

这可能是一个原始文件(已排序且每一行都是唯一的):

a
b
d

一个简单的补丁文件可能看起来像这样(或者在某种程度上如此简单):

+ c
+ e
- b

生成的文件应如下所示(或以任何其他顺序排列,因为无论如何都可以应用 sort):

a
c
d
e

不能使用普通补丁格式,因为它们包含上下文,在这种情况下可能会改变。

由于没有人能给我答案,我创建了一个小的 python 脚本来完成这项工作。 https://github.com/white-gecko/simplepatch

要应用这样的补丁,请调用它(其中生成 outfile.txt

./simplepatch.py -m patch -i infile.txt -p patchfile.txt -o outfile.txt

要生成 patch/diff 调用它(其中生成 patchfile.txt

./simplepatch.py -m diff -i infile.txt -o outfile.txt -p patchfile.txt

使用 commawkgrep 应用此类补丁的 shell 解决方案是:

A=a.txt B=b.txt P=patch.txt; { grep '^-' $P | cut -c 3- | comm -23 $A - ; grep '^+' $P | cut -c 3- } | sort -u > $B

生成补丁文件为:

A=a.txt B=b.txt P=patch.txt; { comm -13 $A $B | awk '{print "+ " [=11=]}' ; comm -23 $A $B | awk '{print "- " [=11=]}' } > $P

Bash 仅读取一次输入文件的备选方案:

要生成补丁,您可以:

comm -3 a.txt b.txt | sed 's/^\t/+ /;t;s/^/- /'

因为 comm 使用制表符分隔不同文件的输出,我们可以使用该制表符来检测是否应该添加或删除行。

要应用补丁,您可以:

{ <patch.txt tee >(grep '^+ ' | cut -c3- >&5) |
grep '^- ' | cut -c3- | comm -13 - a.txt; } 5> >(cat)

tee 将输入(即补丁文件)拆分为两个流。第一部分已过滤 + 并输出到文件描述符 5。文件描述符 5 仅对 >(cat) 打开,因此它仅在 stdout 上输出。第二部分过滤了减号 - 并与 a.txt 连接并输出。因为输出应该是行缓冲的,所以它应该可以工作。