Разница в пробелах между двумя файлами в Linux

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

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

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

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

6 ответов

Решение

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

vimdiff file1 file2

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

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

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

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

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

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

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

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

пример

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

введите описание здесь

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

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

В 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,

Чтобы узнать, где реальные пробелы и вкладки, вы можете заменить их, используя 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

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

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

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

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

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

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

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

И то и другое 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
Другие вопросы по тегам