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

8000
Romski

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

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

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

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

14
Вы проверили на наличие пробела (в конце строки)? Такое пространство будет обнаружено `diff`, но многие редакторы по умолчанию в любом случае не делают это пространство видимым. John1024 9 лет назад 1
Хорошее предложение. Я использовал vim с ": set list on", это показывало "$" в конце строки, а пробела не было. Я обновлю свой вопрос Romski 9 лет назад 0
Если вы пользователь `vim`, то пытались ли вы использовать` vimdiff file1 file2`, чтобы увидеть, в чем различия? John1024 9 лет назад 0
@ John1024 Я не знал о vimdiff, но это выглядит многообещающе. Добавьте это как ответ, и я приму Romski 9 лет назад 0
Vim показывает ^ M только тогда, когда он неправильно определяет окончание строки Unix, но файл на самом деле имеет конец строки DOS. Обычно это происходит, если у вас есть смешанная строка, заканчивающаяся в одном файле, например, применение патча с концом строки, отличным от исходного файла. Когда vim обнаружит, что строка DOS заканчивается правильно, она не показала бы ^ M. Lie Ryan 9 лет назад 1

6 ответов на вопрос

12
Mark Plotnick

On FreeBSD or most Linux systems, you can pipe the output of diff through cat -v -e -t to show whitespace differences.

diff file1 file2 | cat -vet 

Tabs will be shown as ^I, a $ will be shown at the end of each line so that you can see trailing whitespace, and nonprinting characters will be displayed as ^X or M-X.

If you have GNU coreutils (available on most non-busybox Linux distributions), this can be simplified to

diff file1 file2 | cat -A 

On busybox systems, use catv -vet .

6
John1024

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

vimdiff file1 file2 

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

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

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

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

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

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

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

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

пример

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

enter image description here

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

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

2
fencepost

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

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

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

Спасибо за быстрый ответ. Подсчет строк показывает, что в одном файле есть еще 5 строк (я ожидаю, что я внес изменения). Я получил один файл с Linux-машины, а другой был извлечен из репозитория кода на Linux. Я считаю, что при просмотре файла с терминаторами Windows в vim последний символ будет отображаться как ^ M, но это не так. Romski 9 лет назад 0
vim на самом деле достаточно умен, чтобы автоматически определять завершение строки, подробности смотрите на https://stackoverflow.com/questions/3852868. fencepost 9 лет назад 3
Я не знал об этом! Я еще раз проверю Romski 9 лет назад 0
2
TOOGAM

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

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

1
chaos

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

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

Еще лучше, вы можете запустить этот фильтр на выходе diff. Или вы можете использовать готовый фильтр в `cat`, как в http://superuser.com/a/913368/37154 clacke 8 лет назад 0
0
Kevin Panko

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

Оба 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 

Похожие вопросы