Объединить 2 текстовых файла с различиями, помеченными как конфликты - PullRequest
0 голосов
/ 24 января 2019

Я хотел бы видеть полный вывод двух объединенных файлов, где каждое различие помечается так же, как конфликты меток git в файлах. Вариант использования - объединить 2 одинаковых файла конфигурации, проверить объединенный файл и получить визуальные подсказки, чтобы сделать очевидными все различия между файлами, чтобы было легко решить, какой из них выбрать.

Я уже пробовал с diff и diff3, но я мог получить только различия (с diff) или полностью объединенный файл, где отмечены только конфликты (с diff3 -m -A file1 file1 file2). Я использовал git diff и связанные с ним инструменты, но все они объединяют несогласованные изменения, а не отмечают их как различия.

Рабочая среда будет представлять собой скрипт оболочки bash, поэтому было бы неплохо получить желаемый результат с помощью обычных инструментов 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

1 Ответ

0 голосов
/ 26 января 2019

Следуя предложениям из комментариев, я придумал этот лайнер, который, похоже, решил мою проблему. Мне бы хотелось использовать константы для маркеров в подстановках 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 */ для объемного текста, присутствующего только во втором файле. Обратите внимание на n в первом #ifndef и ! в первом #endif комментарии. Поскольку все маркеры отличаются, становится легко выполнять замены.

sed -e $'s/#endif \/\* ! AAAAAAA \*\//=======\\\n>>>>>>> file-from-secret/g': заменяет маркер на

=======
>>>>>>> file-from-secret

Поскольку существует \n, строка подстановки заключена в $'', который правильно интерпретирует символ новой строки. Тем не менее, \ необходимо дважды экранировать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...