如何使用patch和diff合并两个文件并自动解决冲突

Raf*_*l T 23 xml diff patch text-processing merge

我已经阅读了 diff 和 patch,但我不知道如何应用我需要的东西。我想它很简单,所以为了显示我的问题,请使用这两个文件:

一个.xml

<resources>
   <color name="same_in_b">#AAABBB</color>
   <color name="not_in_b">#AAAAAA</color>
   <color name="in_b_but_different_val">#AAAAAA</color>
   <color name="not_in_b_too">#AAAAAA</color>
</resources>
Run Code Online (Sandbox Code Playgroud)

xml文件

<resources>
   <color name="same_in_b">#AAABBB</color>
   <color name="in_b_but_different_val">#BBBBBB</color>
   <color name="not_in_a">#AAAAAA</color>
</resources>
Run Code Online (Sandbox Code Playgroud)

我想要一个输出,看起来像这样(顺序无关紧要):

<resources>
   <color name="same_in_b">#AAABBB</color>
   <color name="not_in_b">#AAAAAA</color>
   <color name="in_b_but_different_val">#BBBBBB</color>
   <color name="not_in_b_too">#AAAAAA</color>
   <color name="not_in_a">#AAAAAA</color>
</resources>
Run Code Online (Sandbox Code Playgroud)

合并应包含符合此简单规则的所有行:

  1. 仅在其中一个文件中的任何行
  2. 如果一行具有相同的名称标签但具有不同的值,则从第二个中获取值

我想在 bash 脚本中应用这个任务,所以如果另一个程序更适合,它不一定需要完成差异和补丁

ale*_*xis 26

你不需要patch这个;它用于提取更改并在没有文件未更改部分的情况下发送它们。

合并文件的两个版本的工具是merge,但正如@vonbrand所写,您需要两个版本不同的“基本”文件。要在没有它的情况下进行合并,请diff像这样使用:

diff -DVERSION1 file1.xml file2.xml > merged.xml
Run Code Online (Sandbox Code Playgroud)

它将包含 C 样式#ifdef/ #ifndef“预处理器”命令中的每组更改,如下所示:

#ifdef VERSION1
<stuff added to file1.xml>
#endif
...
#ifndef VERSION1
<stuff added to file2.xml>
#endif
Run Code Online (Sandbox Code Playgroud)

如果两个文件之间的行或区域不同,则会出现“冲突”,如下所示:

#ifndef VERSION1
<version 1>
#else /* VERSION1 */
<version 2>
#endif /* VERSION1 */
Run Code Online (Sandbox Code Playgroud)

所以将输出保存在一个文件中,然后在编辑器中打开它。搜索出现的任何地方#else,并手动解决它们。然后保存文件并运行它grep -v以摆脱剩余的#if(n)def#endif行:

grep -v '^#if' merged.xml | grep -v '^#endif' > clean.xml
Run Code Online (Sandbox Code Playgroud)

将来,请保存文件的原始版本。merge可以在额外信息的帮助下为您提供更好的结果。(但要小心:merge就地编辑其中一个文件,除非您使用-p. 阅读手册)。


Cod*_*lor 8

sdiff (1) - 文件差异的并排合并

使用该--output选项,这将交互式合并任意两个文件。您可以使用简单的命令来选择更改或编辑更改。

您应该确保EDITOR设置了环境变量。“eb”等命令的默认编辑器通常ed是行编辑器

EDITOR=nano sdiff -o merged.txt file1.txt file2.txt
Run Code Online (Sandbox Code Playgroud)


von*_*and 6

merge(1) 可能更接近你想要的,但这需要你的两个文件有一个共同的祖先。

一种(肮脏的!)方法是:

  1. 去掉第一行和最后一行,grep(1)用来排除它们
  2. 将结果粉碎在一起
  3. sort -u 留下一个排序的列表,消除重复
  4. 替换第一行/最后一行

嗯……大致如此:

echo '<resources>'; grep -v resources file1 file2 | sort -u; echo '</resources>'

可能做。