Вопрос или проблема
Я хотел бы иметь возможность использовать diff и patch, чтобы добавлять новые строки в файл. Чтобы немного прояснить, что я имею в виду:
Исходный файл: test1.repo
exclude=mongo*
exclude=sqlite*
exclude=postgresql*
Новый файл: test2.repo
exclude=mongo*
exclude=postgresql*
exclude=mysql*
Итак, я запускаю команду diff -u test1.repo test2.repo > repo.patch
, чтобы найти различия, это довольно просто. Посмотрев на файл repo.patch
, который я только что создал, я вижу вывод:
exclude=mongo*
-exclude=sqlite*
exclude=postgresql*
+exclude=mysql*
Если я использую patch как есть, он просто перепишет файл данными из test2.repo
. Есть ли способ заставить patch только добавлять новые строки (все, что начинается с +)? Я хотел бы добавлять строки в оригинальный репозиторий, но не уничтожать какие-либо настройки, которые они уже сделали в своем файле.
Публикую в качестве ответа, потому что думал, что комментарий недостаточно виден, скрыт по умолчанию.
Что я делаю:
- использую
diff -e
, чтобы получить скрипт ed, затем - удаляю все команды
d
(обратите внимание, что тела команд, вводящих содержимое, разделены завершающей точкой.
, стоящей самой по себе в строке),
- оставляя только команды
a
- (также, если какая-либо другая команда, кроме
a
илиi
, появится, я заменю ее наa
илиi
).
- (также, если какая-либо другая команда, кроме
- Затем отправляю это через
echo wq | cat script_filename - | ed -s result_filename
, чтобы выполнить скрипт сwq
для записи и выхода в конце, согласно этому ответу на Использование вывода diff -e с sed
И это неправильно.
Я не заметил, но мои файлы на самом деле приходили в беспорядок. Оказывается, номера строк в командах инкрементальны — так что команда 0a
после команды d
означает, что она добавляет, где находится, а не в начале файла.
Ответ или решение
Чтобы добавить новые строки в файл с помощью утилит diff
и patch
, не затрагивая существующие строки, можно воспользоваться некоторыми техниками. В данной ситуации нам нужно устранить возможность удаления или переписывания существующих строк.
Вот шаги, которые можно выполнить для достижения этой цели:
-
Создание патча: Для начала вам нужно создать файл патча с помощью команды
diff -u
. Это создаст стандартный вывод, который будет включать как строки, которые были удалены, так и новые строки, которые были добавлены.diff -u test1.repo test2.repo > repo.patch
-
Форматирование патча: Патч, созданный командой
diff
, будет содержать строки, начинающиеся с-
, что обозначает удаление, и с+
, что обозначает добавление. Чтобы оставить только команды на добавление (строки с+
), вы можете обработать файл патча. Для этого откройтеrepo.patch
в текстовом редакторе и удалите все строки с-
. Либо можно использовать командуsed
:sed -i '/^-/d' repo.patch
-
Использование ed: На этом этапе вам необходимо будет преобразовать оставшиеся команды добавления в формат, который можно будет использовать с командой
ed
. Для этого создайте скрипт, который будет содержать только командыa
. Вы можете выполнить это с помощьюdiff -e
:diff -e test1.repo test2.repo > repo.ed
-
Удаление команд удаления: Откройте файл
repo.ed
и удалите все строки, начинающиеся сd
. Либо используйте:sed -i '/^d/d' repo.ed
-
Выполнение изменений с помощью ed: Наконец, вы можете применить изменения, используя
ed
. Для этого выполните следующую команду:echo wq | cat repo.ed - | ed -s test1.repo
Эти шаги позволят вам добавлять только новые строки в ваш оригинальный файл, не затрагивая уже существующие строки. Таким образом, ваши индивидуальные настройки в файле не будут потеряны, и вы сможете успешно интегрировать новые параметры (например, строки с exclude=mysql*
) в test1.repo
.