14

У меня есть два файла, которые при сравнении с diff показывают, что каждая строка изменилась. Когда я сравниваю их с diff -w (игнорируя пробелы), он показывает несколько минимальных изменений, которые я ожидаю.

Очевидно, между пробелами в каждом файле есть некоторая разница, но я не знаю, что это такое и как их найти. Я попытался отредактировать файлы, чтобы убедиться, что пробел на самом деле является пробелом (в отличие от вкладок), но я не уверен, что еще делать.

Я использовал vim с :set list on чтобы подтвердить, что в конце строк нет пробела.

Я также считаю, что в каждом файле есть разделители строк в Linux, поскольку vim не показывал ^M в конце строк.

6 ответов6

13

В FreeBSD или в большинстве систем Linux вы можете передать вывод diff через cat -v -e -t чтобы показать различия между пробелами.

diff file1 file2 | cat -vet

Вкладки будут отображаться как ^I , в конце каждой строки будет отображаться символ $ , чтобы вы могли видеть конечные пробелы, а непечатаемые символы будут отображаться как ^X или M-X .

Если у вас есть GNU coreutils (доступно в большинстве не занятых дистрибутивов Linux), это можно упростить до

diff file1 file2 | cat -A

В системах busybox используйте catv -vet .

6

Для пользователей vim есть удобная утилита, показывающая точные различия между файлами:

vimdiff file1 file2

Это поместит каждый файл в окна, бок о бок, и различия будут выделены цветом.

Некоторые полезные команды в vimdiff

В то время как в vimdiff , некоторые полезные команды:

  • ]c: перейти к следующему изменению

  • [c: перейти к предыдущему изменению

  • ctrl-W ctrl-W: переключиться в другое окно

  • zo: открытые складки

  • zc: закрыть складки

пример

Вот пример vimdiff в xterm сравнивающий две версии файла конфигурации cups :

Вы можете видеть, что длинные участки одинаковых линий были свернуты. Их можно снова открыть с помощью zo .

Цветовая схема будет варьироваться в зависимости от настроек вашего варианта. В приведенном выше примере, когда строка появляется в одном файле, но не в другом, этой строке выделяется темно-синий фон. В другом файле пропущенные строки обозначены пунктирными линиями. Когда линия появляется в обоих файлах, но имеет некоторые различия, неизмененные части линий имеют розовый фон, а измененные части имеют красный фон.

2

Был ли один из файлов отредактирован на компьютере с Windows?

Стандартное завершение строки в Windows - это CRLF, где в Linux это просто LF (а в Mac это был CR, но я подозреваю, что это изменилось со времен OS X).

Попробуйте wc -l для файлов и посмотрите, сколько строк, а затем посмотрите, не отличается ли разница в размере от количества строк (последняя строка может не заканчиваться в одном файле).

2

od может помочь. Команда Octal Dump может показывать содержимое в шестнадцатеричном формате. Это может помочь вам увидеть, какие байты, включая нулевые байты или неожиданный пробел, находятся в файле. Возможными общими причинами могут быть LF против CRLF, табуляции против пробелов или ASCII против юникода (у которых часто может быть нулевой байт перед каждым обычно видимым байтом). od -x filename должно раскрывать любой из этих шаблонов. Если вы хотите более сложный способ просмотра файла, подойдет любой "шестнадцатеричный редактор". Хорошая вещь в od заключается в том, что, подобно команде cut , она встроена во многие системы Unix. Поэтому часто не требуется отдельная установка.

Если вам нужно, чтобы файлы были более похожими, tr может внести некоторые изменения, а sed может сделать больше. Вероятно, я бы начал с ls -l чтобы увидеть, какой файл больше, затем просмотрите байты, чтобы увидеть, что нужно изменить, а затем измените один из файлов, чтобы они казались более похожими.

1

Чтобы узнать, где настоящие пробелы и вкладки, вы можете заменить их с помощью sed например:

$ cat file
  line 1
  line 2
    line 6
        line 7
$ sed 's/ /-/g; s/\t/<tab>/g' file
--line-1
--line-2
<tab>line-6
<tab><tab>line-7

А теперь сравните два файла.

0

Следующее содержание было скопировано здесь из раздела "вопрос" выше, который был написан Ромски.

И vimdiff и diff file1 file2 | cat -A были очень полезны с точки зрения инструментов.

Наконец, я нашел еще одну проблему. Некоторые из моих файлов были закодированы с помощью UTF-8 BOM. Это было выделено с помощью diff file1 file2 | cat -A . Это проявилось как M-oM-;M-? в начале затронутого файла:

$ diff file1 file2 | cat -A
< package com.mycompany;$
---$
> M-oM-;M-?package com.mycompany;$

Несмотря на ряд проблем, я перечислил несколько команд ниже для тех, кто нуждается в очистке своих файлов:

# recursively remove UTF8 BOM
find . -type f -exec sed -i -e '1s/^\xEF\xBB\xBF//' {} \;

# recursively replace CRLF with LF
find . -type f -print0 | xargs -0 dos2unix

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .