Вы уже используете правильная команда, и судя по последним комментариям, она работает.
Патчи работают не так. Утилита patch
применяет исправление, созданное утилитой diff
, запущенной на двух существующих версиях файла или набора файлов. Две версии статичны, и применение патча преобразует одну в другую (возможны оба направления).
Чтобы просто добавить строки файла ( lines.in
), которые полностью отсутствуют в другом файле ( file.dat
), вы можете использовать comm
] следующим образом ( bash
и ksh93
):
comm -23 <( sort lines.in ) <( sort file.dat ) >>file.dat
Добавленные строки будут отсортированы.
Решение, сохраняющее порядок строк в lines.in
:
grep -v -x -F -f file.dat lines.in >>file.dat
Это будет использовать grep
, чтобы найти все строки в lines.in
который не существует ( -v
) в file.dat
( -f file.dat
), и добавьте их в file.dat
. Полные строки сравниваются как фиксированные ( -x -F
).
Проблема возникает при обновлении файлов конфигурации. Например, вы можете сделать это как функции сценария оболочки:
#!/bin/sh
add_data() {
grep "^$2$" "$1" >/dev/null 2>/dev/null || echo "$2" >>"$1"
}
add_data program.conf "Line 1"
add_data program.conf "Line 2"
В этом примере я привязал выражение так, чтобы совпадали только строки, не содержащие лишнего текста. Но предполагается, что в данных нет метасимволов. Этот вызов не будет добавлять буквальный текст:
add_data program.conf ".*Line 2$"
Вы можете обойти это, экранировав символы, которые могут вызвать проблемы с grep.
Комментаторы отмечают, что можно обойти эту проблему, используя параметр POSIX -x
:
Учитывать только строки ввода, в которых используются все символы в строка, исключающая завершение, чтобы соответствовать всей фиксированной строке или регулярному выражению, чтобы соответствовать строкам.
со следующим результатом:
#!/bin/sh
add_data() {
grep -F -x "$2" "$1" >/dev/null 2>/dev/null || echo "$2" >>"$1"
}
add_data program.conf "Line 1"
add_data program.conf "Line 2"
add_data program.conf ".*Line 2$"
Если вы поместите только эти строки для добавления в файл, например:
Line 1
Line 2
, вы можете сделать:
pcregrep -xqM "\Q$(cat that-file)\E" file-to-patch ||
cat that-file >> file-to-path
Предполагается, что этот файл
не содержит \ E
и не заканчивается пустыми строками.