Следуя предложениям из комментариев, я придумал этот лайнер, который, похоже, решил мою проблему.
Мне бы хотелось использовать константы для маркеров в подстановках 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
, строка подстановки заключена в $''
, который правильно интерпретирует символ новой строки. Тем не менее, \
необходимо дважды экранировать.