用于排序唯一文件的简单 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
使用 comm
、awk
和 grep
应用此类补丁的 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
连接并输出。因为输出应该是行缓冲的,所以它应该可以工作。
我怎么能写一个简单的 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
使用 comm
、awk
和 grep
应用此类补丁的 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
连接并输出。因为输出应该是行缓冲的,所以它应该可以工作。