Основное:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
Опция q отменяет вывод отличающихся строк и печатает только сообщение о том, имеются ли отличия. Опция -i применяется в случае, если необходимо игнорировать регистр в сравниваемых файлах. Часто используемые опции -u и -c выводят информацию, соответственно, в обобщенном (unified) и контекстном (context) форматах. ps > ps1.txt ps > ps2.txt diff ps1.txt ps2.txt diff -u ps1.txt ps2.txt Особенностью этих форматов является вывод информации об именах сравниваемых файлов. Эта информация может быть использована для реконструкции одного из сравниваемых файлов по-другому с помощью известных отличий этих файлов. Для этого используется утилита patch, позволяющая обновлять содержимое файлов с помощью так называемых "заплаток" (patches). Файлы-"заплатки" создаются с помощью утилиты diff, а обновление файлов производится утилитой patch. Пример с файлами f1 и f2 0. создаем файлы f1.txt и f2.txt cat > f1.txt << . bad file . cat > f2.txt << . good file . 1. Сравниваем файлы diff -Nau f1.txt f2.txt > patch-f1-from-f2 2. Применяем патч patch -p0 < patch-f1-from-f2 |
Создание и применение патча для директории:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Допустим, есть две директории dir1 и dir2 diff -Naur ./dir1 ./dir2r > ./patch Теперь, чтобы установить патч, нужно запустить: patch -p0 < ./patch Только не забудьте, что патчиться будет каталог ./dir1 Здесь главное, на что нужно обратить внимание, — это знак перенаправления < и -p Без перенаправления < программа patch будет спрашивать, какой файл патчить. Второй вариант — использовать ключ -i в место перенаправления <, т.е. patch -p0 -i ./patch Подведем итог: patch -p0 < ./patch - этой командой мы устанавливаем патч patch -p0 -i patch1 - этой командой мы устанавливаем патч Но если любую из команд повторить то у нас спросят желаем ли мы откатить все обратно, и если нажмем "y" то все что сделал патч будет отменено. |
Как работает -p в patch
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
-p num или --strip= num Удалить наименьший префикс, содержащий num начальных косых черт, из каждое имя файла, найденное в файле исправления. Последовательность одного или несколько смежных косых черт считаются как одна косая черта. Этот управляет тем, как обрабатываются имена файлов, найденные в файле исправления, если вы храните свои файлы в другом каталоге, чем человек, который отправил патч. Например, если предположить, имя файла в файле патча было /u/howard/src/blurfl/blurfl.c установка -p0 дает полное имя файла без изменений, -p1 дает u/howard/src/blurfl/blurfl.c без косой черты в начале, -p4 дает blurfl/blurfl.c и отсутствие указания -p вообще дает вам blurfl.c . Что бы в конечном итоге ищете либо в текущем каталоге, либо каталог, указанный параметром -d . |
Пример, строчный патч:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
0. Создаем два файла cat > 1 << "EOF" Привет Мир!!! EOF cat > 2 << "EOF" Привет Москва! EOF 1. Сравниваем их с помощью diff 1 2 diff 1 2 1c1 < Привет Мир!!! --- > Привет Москва! 2. Сравниваем их с помощью diff 2 1 1c1 < Привет Москва! --- > Привет Мир!!! 3. Пояснение вывода diff 1c1 показывает номер строки и то, что с ней надо сделать. Обратите внимание, что может быть сразу несколько строк(например, 12,15, что означает со строки 12 до строки 15). Символ "c" означает, что патч заменит эту строку. Есть еще два других символа: "a" и "d". Они означают "добавить"(add) и "удалить"(delete) соответственно. Таким образом, синтаксис следующий: (номер строки или диапазон строк)(c,a или d)(номер строки или диапазон строк), хотя когда используются "a" или "d", одна из частей (номер строки или диапазон строк) может содержать только номер одной строки. Когда используется "c", номера строк слева - это строки в оригинальном файле, которые надо заменить строками, находящимися в патче, а номера строк справа - это строки, которые должны быть в пропатченном файле. Когда используется "a", номер слева может быть только номером одной строки, который показывает, где надо добавить строку в пропатченном файле, а номера строк справа - это строки, которые должны быть в пропатченном файле. Когда используется "d", номера строк слева - это строки, которые надо удалить, чтобы получить пропатченную версию файла, а номер строки справа может быть только номером одной строки, который показывает где будут строки в пропатченном файле, если они не будут удалены. Вы можете подумать, что последний номер не нужен, но не забывайте, что патч можно применить для восстановления исходного файла. Знак "<" означает, что патч должен удалить символы после этого знака, а знак ">" означает, что символы после этого знака надо добавить. Когда надо заменить строки ("c" между номерами строк), вы увидите оба знака: и "<", и ">". Когда надо добавить строку ("a" между номерами строк), вы увидите только знак ">", а когда надо удалить строку ("d" между номерами строк), вы увидите только знак "<". Строка "\ No newline at end of file" появилась из-за того, что я не не нажал enter после того как набрал слова. Считается хорошим тоном заканчивать текстовый файл пустой строкой. Некоторым программам она необходима для работы. Поэтому эта строка появилась после работы команды diff. 4. Сделаем патчи для файлов: diff 2 1 > 1.patch diff 1 2 > 2.patch 5. Применим патч patch 2 -i 1.patch -o 3 patch 1 -i 2.patch -o 4 6. Проверяем что получилось: cat 3 Привет Мир!!! cat 4 Привет Москва! 6. Пробуем применить патч вот так вот patch 1 -i 1.patch -o 5 patch 2 -i 2.patch -o 6 7. Вот что мы получим: cat 5 Привет Москва! cat 6 Привет Мир!!! 8. Контекстный патч |
Пример контекстный патч:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
До этого мы создали патч, используя нормальный формат команды diff. Однако этот формат не обеспечивает контекстной зависимости, а использует строки целиком. Создадим патч для того же файла, но используя контекстный формат 0. Создаем патчи diff -c 1 2 > 1.patch diff -c 2 1 > 2.patch 1. Проверяем что получилось cat 1.patch *** 1 2024-02-14 12:46:35.842689004 +0300 --- 2 2024-02-14 12:46:35.842689004 +0300 *************** *** 1 **** ! Привет Мир!!! --- 1 ---- ! Привет Москва! cat 2.patch *** 2 2024-02-14 12:46:35.842689004 +0300 --- 1 2024-02-14 12:46:35.842689004 +0300 *************** *** 1 **** ! Привет Москва! --- 1 ---- ! Привет Мир!!! 2. Что мы тут видим: Как вы видите, здесь включено имя файла. Это значит, что нам не придется набирать его во время применения патча. Далее идет дата и время последнего изменения файла. строка с "*" показывает начало изменений. Они показывают, что надо сделать со следующим блоком текста. Два номера 1 - это номера строк (здесь тоже может быть сразу несколько строк), а "!" означает, что строки надо заменить. Строка с "!" перед тремя "-" должна быть заменена второй строкой с "!", которая идет после трех "-"(конечно сам ! не будет включен; это синтаксис контекстного формата). Как вы можете видеть, здесь нет знаков "c", "a" и "d". Действие, которое нужно сделать, определяется символом в начале строки. "!" означает замену. Другие символы - "+", "-" и " " (пробел). "+" означает добавление, "-" означает удаление, а " " означает ничего не делать: патч использует его чтобы убедиться, что он изменяет правильную часть файла. 3. Пробуем применить патч: patch -i 1.patch -o 3 patch -i 2.patch -o 4 4. Проверяем что получилось cat 3 Привет Москва! cat 4 Привет Мир!!! 5. Да и еще можно применить патч вот так: patch -i 1.patch patch -i 2.patch 6. Проверяем: cat 1 Привет Москва! cat 2 Привет Мир!!! 7. Восстановление оригинального файла из пропатченного #patch -p0 -R -i patchfile.patch patch -p0 -R -i 1.patch patch -p0 -R -i 2.patch 8. Проверяем что получилось cat 1 Привет Мир!!! cat 2 Привет Москва! |
Ссылки
1 |
https://www.ylsoftware.com/news/243 |