Результат diff двух файлов с коммутируемыми линиями говорит, что отсутствует одна и та же строка дважды

Я пытаюсь понять команду linux diff на двух файлах, строки которых являются просто перестановкой друг друга, но не могут получить вывод, который он генерирует. Рассмотрим три команды ниже:

[myPrompt]$ cat file1 apples oranges [myPrompt]$ cat file2 oranges apples [myPrompt]$ diff file1 file2 1d0 < apples 2a2 > apples 

Может кто-то объяснить вышеупомянутый критический вывод от diff.

  1. Почему в выводе нет упоминания о «апельсинах»?
  2. Что означает 2a2 и 2a2 ?

Я понимаю из этого ответа, что:

«<» означает, что строка отсутствует в файле2, а «>» означает, что строка отсутствует в файле1

НО это не объясняет, почему в выходе отсутствуют апельсины.

4 Solutions collect form web for “Результат diff двух файлов с коммутируемыми линиями говорит, что отсутствует одна и та же строка дважды”

Чтобы понять отчет, помните, что diff является предписывающим, описывая, какие изменения необходимо внести в первый файл ( file1 ), чтобы сделать его таким же, как второй файл ( file2 ).

В частности, d в 1d0 означает delete, а a в 2a2 означает добавление .

Таким образом:

  • 1d0 означает, что строка 1 должна быть удалена в file1 ( apples ). 0 в 1d0 означает, что строка 0 находится там, где они появлялись во втором файле ( file2 ), если бы они не были удалены. Это означает, что при смене file2 на file1 (назад) добавьте строку 1 file1 после строки 0 file2 .
  • 2a2 означает добавление второй строки ( oranges ) из 2a2 вторую строку file1 (после удаления первой строки в file1 , oranges переключенных в строку 1)

Рассмотрим эти файлы:

file1 :

 # cat file1 apples pears oranges peaches 

file2 :

 # cat file2 oranges apples peaches ananas banana 

Как работает diff , учитывая, что он основан на заказе:

  1. diff читает первый блок строк file1 и file2 и пытается найти равные строки:

      file1 file2 differences on left (<) or right side (>) apples <apples pears <pears ------------------------------- ->oranges ->oranges peaches apples peaches ananas banana 
  2. Теперь он пропустит все строки, которые равны в обоих файлах, а именно oranges в этом случае:

      file1 file2 differences on left (<) or right side (>) apples <apples pears <pears oranges oranges ------------------------------- ->peaches ->apples peaches ananas banana 
  3. Теперь найдите другой набор похожих строк и распечатайте отличия:

      file1 file2 differences on left (<) or right side (>) apples <apples pears <pears oranges oranges apples >apples ------------------------------- ->peaches ->peaches ananas banana 
  4. Пропустить похожие строки

      file1 file2 differences on left (<) or right side (>) apples <apples pears <pears oranges oranges apples >apples peaches peaches ------------------------------- -> ->ananas banana 
  5. Найдите идентичные строки, если это возможно, и распечатайте различия:

     line_file1 file1 line_file2 file2 differences on left (<) or right side (>) 1 apples <apples 2 pears <pears 3 oranges 1 oranges 2 apples >apples 4 peaches 3 peaches 4 ananas >ananas 5 banana >banana ----------------------------------------------- 

Теперь, если я делаю diff file1 file2 :

 # diff file1 file2 1,2d0 < apples < pears 3a2 > apples 4a4,5 > ananas > banana 

Теперь просто объяснить, что означает выход diff :

Чтобы file1 равен file2 :

  • 1,2d0 : Удалить ( d ) строки 1-2 из file1 и изменить строку 0 file2 соответственно
  • 3a2 : Добавить ( a ) в строку 3 file1 строки 2 file2
  • 4a4,5 : добавить в строку 4 строк file1 4-5 file2

diff сравнивает file1 с file2 по строкам и устанавливает различия во временной памяти. После того, как file1 равен file2 до первого появления строки в file1 , что также встречается в file2 , все строки, которые равны до разницы, не упоминаются, часто обозначаются как --- . В этом случае существует только одна подобная линия, которая представляет собой oranges . Обратите внимание, что я сказал file1 равным file2 , поэтому file1 рассматривается относительно file2 а не наоборот.

Вывод связан с первым указанным файлом, в данном случае file1 .

Там они:

 $ diff file1 file2 1d0 < apples 2a2 > apples $ diff file2 file1 1d0 < oranges 2a2 > oranges 

Стандартный (старый) формат вывода отображает разницу между файлами без окружающего текста с областями, где файлы отличаются.

Например: 1d0 < (delete) означает, что яблоки должны быть удалены из первой строки 2a2 > , а 2a2 > (append) означает, что яблоки должны быть добавлены в file2 во второй строке, поэтому оба файла могут быть сопоставлены.

Документация, доступная в info diff объясняет это еще больше:

Отображение различий без контекста

«Нормальный» формат вывода diff отображает каждую комбинацию различий без какого-либо окружающего контекста. Иногда такой вывод является самым ясным способом увидеть, как изменились строки, без беспорядка соседних неизмененных строк (хотя вы можете получить похожие результаты с контекстными или унифицированными форматами, используя 0 строк контекста). Однако этот формат больше не используется для рассылки патчей; для этой цели формат контекста и унифицированный формат являются превосходными. Обычный формат является стандартным для совместимости со старыми версиями diff и стандартом POSIX. Используйте параметр --normal чтобы явно выбрать этот формат вывода.

Подробное описание нормального формата

Нормальный выходной формат состоит из одного или нескольких фрагментов различий; каждый кусок показывает одну область, где файлы отличаются. Обычные форматы выглядят так:

  CHANGE-COMMAND < FROM-FILE-LINE < FROM-FILE-LINE... --- > TO-FILE-LINE > TO-FILE-LINE... 

Существует три типа команд изменения. Каждый из них состоит из номера строки или разделенного запятыми диапазона строк в первом файле, одного символа, указывающего вид изменения, который должен быть сделан, и номера строки или диапазона строк, разделенных запятыми, во втором файле. Все номера строк являются исходными номерами строк в каждом файле. Типы команд изменения:

LaR Добавьте строки в диапазон R второго файла после строки L первого файла. Например, 8a12,15 означает добавление строк 12-15 файла 2 после строки 8 файла 1; или, если изменить файл 2 в файл 1, удалите строки 12-15 файла 2.

FcT Заменить строки в диапазоне F первого файла с строками в диапазоне T второго файла. Это похоже на комбинированное добавление и удаление, но более компактное. Например, 5,7c8,10 означает изменение строк 5-7 файла 1 для чтения в виде строк 8-10 файла 2; или, если изменить файл 2 в файл 1, измените строки 8-10 файла 2, чтобы читать строки 5-7 файла 1.

RdL Удалить строки в диапазоне R из первого файла; строка L, где они появлялись бы во втором файле, если бы они не были удалены. Например, 5,7d3 означает удаление строк 5-7 файла 1; или, если сменить файл 2 в файл 1, добавьте строки 5-7 файла 1 после строки 3 файла 2.

Смотрите также:

  • Объяснение команды Linux diff с примерами
  • Понимание выходного сигнала

Поэтому, чтобы увидеть апельсины, вам придется различать их либо бок о бок, либо используя единый контекст.

В примере:

 $ diff -y file1 file2 apples < oranges oranges > apples $ diff -u file1 file2 @@ -1,2 +1,2 @@ -apples oranges +apples 
  • diff сообщает, что два файла отличаются друг от друга, хотя они одинаковы!
  • diff -horizon-lines = строки объяснены
  • diff - выходные номера строк
  • Минимальная разница между двумя текстами
  • Diff статистики каталогов sumarry (git diff --stat, как для non-git repo)
  • Что означает тире «-» в командной строке Unix?
  • Использование diff для отображения как содержимого новых файлов, так и создания новых пустых файлов
  • Есть ли bdiff (1) в Linux?
  • Как я могу получить коэффициент разницы с помощью «diff» или другой команды?
  • Diff: сравнивать только если файл существует, а не содержимое
  • Используйте Diff to Exclude Quote Symbol - "
  • Linux и Unix - лучшая ОС в мире.