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


15

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

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

Я використовував vim, :set list onщоб підтвердити, що в кінці рядків не було пробілу.

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


1
Чи перевірили ви пробіл пробілів (в кінці рядка)? Такий простір буде виявлено, diffале багато редакторів, за замовчуванням, все одно не роблять цей простір видимим.
John1024

Гарна пропозиція. Я використав vim з ": set list on", це показало "$" в кінці рядка, і не було пробілу. Я
оновлю

Якщо ви vimкористувач, чи намагалися ви використати, vimdiff file1 file2щоб побачити, в чому полягають відмінності?
John1024

@ John1024 Я не знав про vimdiff, але це виглядає перспективно. Додайте його як відповідь, і я прийму
Ромський,

1
Vim показує ^ M лише тоді, коли він неправильно виявляє закінчення рядка Unix, але у файлу фактично закінчується рядок DOS. Зазвичай це трапляється, якщо у вас є змішаний рядок, що закінчується в одному файлі, наприклад, застосовуючи виправлення з іншим закінченням рядка, ніж оригінальний файл. Якщо vim виявить правильне закінчення рядка DOS, він не показав би ^ M.
Лежати Райан

Відповіді:


7

Для vimкористувачів є зручна утиліта для показу точних відмінностей між файлами:

vimdiff file1 file2

Це помістить кожен файл у вікна, поруч та відмінності із виділеним кольором.

Деякі корисні команди, коли в vimdiff

У той час як vimdiffдеякі корисні команди:

  • ]c: перейти до наступної зміни

  • [c: перехід до попередньої зміни

  • ctrl-W ctrl-W: перехід на інше вікно

  • zo: відкриті складки

  • zc: щільні складки

Приклад

Ось приклад vimdiffв xtermпорівняння двох версій cupsфайлу конфігурації:

введіть тут опис зображення

Видно, що довгі ділянки однакових ліній згорнуті. Їх можна знову відкрити за допомогою zo.

Колірна гамма змінюватиметься залежно від налаштувань Вашого параметра. У наведеному вище прикладі, коли рядок з'являється в одному файлі, а не в іншому, цьому рядку надається темно-синій фон. В іншому файлі пропущені рядки позначені пунктирними лініями. Коли рядок з'являється в обох файлах, але має деякі відмінності, незмінені частини рядків мають рожевий фон, а змінені частини мають червоний фон.


14

У FreeBSD або більшості систем Linux ви можете передавати висновки diff через, cat -v -e -tщоб відобразити відмінності між пробілами.

diff file1 file2 | cat -vet

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

Якщо у вас є GNU coreutils (доступний у більшості дистрибутивів Linux без зайнятості), це можна спростити до

diff file1 file2 | cat -A

У системах зайнятих використовуйте catv -vet.


2

Чи редагувався один із файлів на машині Windows?

Стандартне завершення рядків у Windows - це CRLF, де в Linux це просто LF (а на Macs - це було CR, але я підозрюю, що це змінилося після OS X).

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


Дякуємо за швидку відповідь. Якщо підрахунок рядків показує, що в одному файлі є ще 5 рядків (я очікую цього, коли я вносив зміни). Я отримав один файл з машини Linux, а інший був перевірений із сховища коду в Linux. Я вважаю, що перегляд файлу з термінаторами Windows у vim покаже останній символ як ^ M, і це не так.
Ромський

3
ВІМ насправді досить розумні автоопределение закінчення лінії, см stackoverflow.com/questions/3852868 для деталей.
огорожа

Я про це не знав! Я ще раз перевірю
Ромський,

2

odможе допомогти. Команда Octal Dump може відображати вміст у шістнадцятковій формі. Це допоможе вам побачити, які байти, включаючи нульові байти чи несподіване пробіл, є у файлі. Можливими поширеними причинами можуть бути LF проти CRLF, вкладки проти пробілів або ASCII проти Unicode (які часто можуть мати лише нульовий байт перед кожним байтом, що нормально бачиться). 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

А тепер порівняйте два файли.


Ще краще, ви можете запустити цей фільтр на різному виході. Або ви можете використовувати готовий фільтр в cat, як у superuser.com/a/913368/37154
clacke

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.