linux-labs

Вики / Базовые команды

diff и patch

Сравнение файлов и применение патчей; сравнить конфиги, увидеть изменения.

diff показывает различия между файлами; patch применяет такие различия. Полезно сравнить «было/стало» в конфигах, перенести правку, проверить, что изменилось.

diff old.conf new.conf            # построчные различия
diff -u old.conf new.conf         # унифицированный формат (как в git/патчах)
diff -u a b                       # unified diff (читаемо, для патчей)
diff -r dir1 dir2                 # рекурсивно по каталогам
diff -qr dir1 dir2                # только какие файлы отличаются (быстро)
diff --color=auto -u a b          # с цветом
diff -w a b                       # игнорировать пробелы ; -i регистр ; -B пустые строки
diff <(cmd1) <(cmd2)              # сравнить ВЫВОД двух команд (process substitution)
diff <(sort a) <(sort b)          # сравнить без учёта порядка строк

# сделать и применить патч
diff -u orig.conf new.conf > change.patch
patch orig.conf < change.patch    # применить
patch -p1 < change.patch          # из git-патча (срезать 1 уровень пути)
patch --dry-run -p1 < change.patch  # проверить без записи
patch -R < change.patch           # откатить (reverse)
vimdiff a b                       # интерактивное сравнение бок о бок
# свои отличия от пакетного дефолта
diff -u /etc/svc/conf.dpkg-dist /etc/svc/conf

# что изменится перед применением (git-style)
git diff > my.patch ; patch --dry-run -p1 < my.patch

# три файла (общий предок + две версии)
diff3 mine.txt base.txt theirs.txt

# подсветка различий по словам, а не строкам
wdiff old.txt new.txt | colordiff

patch: Hunk FAILED / .rej файлы

Контекст в целевом файле уже изменился. Смотри *.rej (отклонённые куски), применяй вручную или возьми свежий патч. patch --dry-run проверит без записи.

Не знаю, какой -p уровень

git-патчи обычно patch -p1 (срезает a/, b/). Если пути не совпали — пробуй -p0/-p1. patch спросит имя файла, если не нашёл сам.

Слишком шумный diff (пробелы/CRLF/регистр)

diff -w (игнор пробелов), -i (регистр), -B (пустые). CRLF — приведи концы строк (sed -i 's/\r$//', см. sed-awk).

Сравнить вывод команд, а не файлы

diff <(cmd1) <(cmd2) — process substitution (bash). Удобно: diff <(ssh h1 'rpm -qa'|sort) <(ssh h2 'rpm -qa'|sort).

diff -u a b                       # читаемые различия
diff -qr dir1 dir2                # какие файлы отличаются
diff <(cmd1) <(cmd2)              # сравнить вывод команд
diff -u orig new > p.patch ; patch orig < p.patch
patch --dry-run -p1 < git.patch ; patch -R < p.patch   # проверка / откат
vimdiff a b                       # бок о бок

См. также