Разница в пробелах между двумя файлами в 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