合并标记为冲突的差异的 2 个文本文件
Merge 2 text files with differences marked as conflicts
我想查看 2 个合并文件的完整输出,其中每个差异都以与 git 标记文件冲突相同的方式标记。
用例是合并 2 个相似的配置文件,检查合并后的文件,并提供视觉提示以明确文件之间的所有差异,以便轻松决定选择哪个文件。
我已经尝试过使用 diff 和 diff3,但我只能得到差异(使用 diff)或仅标记冲突的完全合并文件(使用 diff3 -m -A file1 file1 file2
)。我用过 git diff 和相关工具,但它们都合并了不冲突的更改,而不是将它们标记为差异。
运行 环境将是一个 bash shell 脚本,因此最好使用常用的 linux 工具获得所需的输出。
示例:
文件 1 的内容:
environment:
base_branch: master
branch: this_is_the_same_for_both_files
文件 2 的内容:
environment:
base_branch: a_different_base_branch
branch: this_is_the_same_for_both_files
a_new_key: the_new_key_value
期望的输出:
environment:
<<<<< file1
base_branch: master
=====
base_branch: a_different_base_branch
>>>>> file2
branch: this_is_the_same_for_both_files
<<<<< file1
=====
a_new_key: the_new_key_value
>>>>> file2
根据评论中的建议,我想出了这个似乎解决了我的问题的班轮。
我本来想在 sed
替换中对标记使用常量,但显然使用包含 \n
和 sed
的变量来表示 mac os 并不简单.
即使在 docker alpine:3.8 中使用 diffutils,此代码似乎也能正常工作。
其他选项(brew gnu-sed 和类似选项)可能不容易移植。
diff -D AAAAAAA "${path}" <(echo -n "$decrypted") | \
sed -e $'s/#ifndef AAAAAAA/<<<<<<< file-on-disk/g' | \
sed -e $'s/#endif \/\* ! AAAAAAA \*\//=======\\n>>>>>>> file-from-secret/g' | \
sed -e $'s/#else \/\* AAAAAAA \*\//=======/g' | \
sed -e $'s/#ifdef AAAAAAA/<<<<<<< file-on-disk\\n=======/g' | \
sed -e $'s/#endif \/\* AAAAAAA \*\//>>>>>>> file-from-secret/g';
解释:
diff -D AAAAAAA "${path}" <(echo -n "$decrypted")
:输出带有“#ifdef NAME”差异的合并文本。我使用 AAAAAAA 作为标记名称。 Diff 使用 #ifndef AAAAAAA
和 #endif /* ! AAAAAAA */
包围仅存在于第一个文件中的文本,使用 /#ifdef AAAAAAA
和 #endif /* AAAAAAA */
包围仅存在于第二个文件中的文本。请注意第一个 #ifndef
中的 n
和第一个 #endif
注释中的 !
。由于所有标记都不同,因此很容易进行替换。
sed -e $'s/#endif \/\* ! AAAAAAA \*\//=======\\n>>>>>>> file-from-secret/g'
:将标记替换为
=======
>>>>>>> file-from-secret
因为有 \n
,替换字符串用 $''
封装 os,这可以正确解释换行符。但是,\
需要双重转义。
我想查看 2 个合并文件的完整输出,其中每个差异都以与 git 标记文件冲突相同的方式标记。 用例是合并 2 个相似的配置文件,检查合并后的文件,并提供视觉提示以明确文件之间的所有差异,以便轻松决定选择哪个文件。
我已经尝试过使用 diff 和 diff3,但我只能得到差异(使用 diff)或仅标记冲突的完全合并文件(使用 diff3 -m -A file1 file1 file2
)。我用过 git diff 和相关工具,但它们都合并了不冲突的更改,而不是将它们标记为差异。
运行 环境将是一个 bash shell 脚本,因此最好使用常用的 linux 工具获得所需的输出。
示例:
文件 1 的内容:
environment:
base_branch: master
branch: this_is_the_same_for_both_files
文件 2 的内容:
environment:
base_branch: a_different_base_branch
branch: this_is_the_same_for_both_files
a_new_key: the_new_key_value
期望的输出:
environment:
<<<<< file1
base_branch: master
=====
base_branch: a_different_base_branch
>>>>> file2
branch: this_is_the_same_for_both_files
<<<<< file1
=====
a_new_key: the_new_key_value
>>>>> file2
根据评论中的建议,我想出了这个似乎解决了我的问题的班轮。
我本来想在 sed
替换中对标记使用常量,但显然使用包含 \n
和 sed
的变量来表示 mac os 并不简单.
即使在 docker alpine:3.8 中使用 diffutils,此代码似乎也能正常工作。 其他选项(brew gnu-sed 和类似选项)可能不容易移植。
diff -D AAAAAAA "${path}" <(echo -n "$decrypted") | \
sed -e $'s/#ifndef AAAAAAA/<<<<<<< file-on-disk/g' | \
sed -e $'s/#endif \/\* ! AAAAAAA \*\//=======\\n>>>>>>> file-from-secret/g' | \
sed -e $'s/#else \/\* AAAAAAA \*\//=======/g' | \
sed -e $'s/#ifdef AAAAAAA/<<<<<<< file-on-disk\\n=======/g' | \
sed -e $'s/#endif \/\* AAAAAAA \*\//>>>>>>> file-from-secret/g';
解释:
diff -D AAAAAAA "${path}" <(echo -n "$decrypted")
:输出带有“#ifdef NAME”差异的合并文本。我使用 AAAAAAA 作为标记名称。 Diff 使用 #ifndef AAAAAAA
和 #endif /* ! AAAAAAA */
包围仅存在于第一个文件中的文本,使用 /#ifdef AAAAAAA
和 #endif /* AAAAAAA */
包围仅存在于第二个文件中的文本。请注意第一个 #ifndef
中的 n
和第一个 #endif
注释中的 !
。由于所有标记都不同,因此很容易进行替换。
sed -e $'s/#endif \/\* ! AAAAAAA \*\//=======\\n>>>>>>> file-from-secret/g'
:将标记替换为
=======
>>>>>>> file-from-secret
因为有 \n
,替换字符串用 $''
封装 os,这可以正确解释换行符。但是,\
需要双重转义。