我从其他人那里继承了一组html文件的两个版本的维护,一个版本带翻译,更大,另一个版本,不带翻译,更短。短文件和长文件的正文仅在包含翻译的行上有所不同。但是,这些文件中还有一些不常见的特定内容,必须保持不变。
short.html
Salve<br/>
Quomodo te habes?<br/>
Some lines specific to short.html
long.html
Salve<br/>
Hello!<br/>
Quomodo te habes?<br/>
How do you do?<br/>
Some other lines specific to long.html
我用来编辑较短的一个,为了不重复两次,我查看了与GNU diff
的区别以创建补丁文件,以便对较大的文件应用相同的更正。
diff short.html.orig short.html > short.diff
patch -z .orig long.html short.diff
这是一种魅力,因为patch
足够聪明,可以跳过垃圾来寻找修补程序,直到我不得不纠正短文件中的相邻行。
在这种情况下,diff
命令的输出如下:
1,2c1,2
< Salve<br/>
< Quomodo te habes?<br/>
---
> Salvete<br/>
> Quomodo vos habetis?<br/>
并且补丁被拒绝,因为我认为patch
找不到两行包含Salve...
和Quomodo...
的任何块以替换在long.html中,因为这两行在每行之后插入翻译的较长版本中,不再相邻。只要逐行应用补丁,它就可以很好地工作,但是当补丁被分组为一个块(他们称为块)时,它将不再起作用。
我的问题是:如何防止diff
将要修补的行分组为块,以便逐行应用修补程序?
不用多说,我希望将上面的diff
命令的输出更改为:
1c1
< Salve<br/>
---
> Salvete<br/>
2c2
< Quomodo te habes?<br/>
---
> Quomodo vos habetis?<br/>
答案 0 :(得分:2)
我找到了解决问题的方法,而不是一种解决方法,在该方法中,我不更改diff
的行为。使用AWK,可以处理其输出以将具有多行的粗线切成一行的切片:
diffungroup
awk -F ',|c' ' # process lines as "3,4c3,4" and following lines
/[0-9]+,[0-9]+c[0-9]+,[0-9]+/ {
ss = $1; se = $2; ds = $3; de = $4;
for (i = ss; i <= se; i++) {
getline
a[i] = $0
}
getline # skip "---"
i = ss
for (j = ds; j <= de; j++) {
print i "c" j
print a[i++]
print "---"
getline
print $0
}
next
}
{ print }
' "$@"
它像这样转换diff
的输出:
1,2c1,2
< Salve<br/>
< Quomodo te habes?<br/>
---
> Salvete<br/>
> Quomodo vos habetis?<br/>
进入:
1c1
< Salve<br/>
---
> Salvete<br/>
2c2
< Quomodo te habes?<br/>
---
> Quomodo vos habetis?<br/>
在上述问题中解释的上下文中,我以另一种方式调用它:
diff short.html.orig short.html > short.diff
./diffungroup short.diff > long.diff
patch -z .orig long.html long.diff
而且,正如我上面说的,它就像一种魅力。