Sự khác biệt về khoảng trắng giữa hai tệp trên Linux


15

Tôi có hai tệp mà khi tôi so sánh với diff cho thấy mọi dòng đã thay đổi. Khi tôi so sánh chúng với diff -w(bỏ qua khoảng trắng), nó sẽ hiển thị một vài thay đổi tối thiểu mà tôi mong đợi.

Rõ ràng có một số khác biệt giữa khoảng trắng trong mỗi tệp, nhưng tôi không biết chúng là gì hoặc làm thế nào để tìm thấy chúng. Tôi đã thử chỉnh sửa các tệp để đảm bảo rằng khoảng trắng thực sự là các ký tự khoảng trắng (trái ngược với các tab) nhưng không chắc chắn phải làm gì khác.

Tôi đã sử dụng vim với :set list onđể xác nhận không có dấu cách ở cuối dòng.

Tôi cũng tin rằng mỗi tệp có các đầu cuối dòng Linux vì vim không hiển thị ^Mở cuối dòng.


1
Bạn đã kiểm tra dấu vết khoảng trắng (ở cuối dòng) chưa? Không gian như vậy sẽ được phát hiện bởi diffnhưng nhiều biên tập viên không, theo mặc định, làm cho không gian này hiển thị.
John1024

Gợi ý tốt. Tôi đã sử dụng vim với ": set list on", nó hiển thị "$" ở cuối dòng và không có dấu cách. Tôi sẽ cập nhật câu hỏi của tôi
Romski 4/2/2015

Nếu bạn là vimngười dùng, bạn đã thử sử dụng vimdiff file1 file2để xem sự khác biệt là gì chưa?
John1024

@ John1024 Tôi không biết về vimdiff, nhưng có vẻ đầy hứa hẹn. Thêm nó dưới dạng câu trả lời và tôi sẽ chấp nhận
Romski 4/2/2015

1
Vim chỉ hiển thị ^ M khi nó định nghĩa sai một dòng kết thúc Unix nhưng tệp thực sự có dòng kết thúc DOS. Thông thường, điều này xảy ra nếu bạn có dòng kết thúc trong một tệp, ví dụ: áp dụng một bản vá với kết thúc dòng khác với tệp gốc. Khi vim phát hiện dòng DOS kết thúc chính xác, nó sẽ không hiển thị ^ M.
Lie Ryan

Câu trả lời:


7

Đối với vimngười dùng, có một tiện ích tiện dụng để hiển thị sự khác biệt chính xác giữa các tệp:

vimdiff file1 file2

Điều này sẽ đặt từng tệp trong các cửa sổ, cạnh nhau và sự khác biệt với màu được tô sáng.

Một số lệnh hữu ích khi trong vimdiff

Trong khi ở vimdiff, một số lệnh hữu ích là:

  • ]c: chuyển sang thay đổi tiếp theo

  • [c: chuyển sang thay đổi trước đó

  • ctrl-W ctrl-W: chuyển sang cửa sổ khác

  • zo: nếp gấp mở

  • zc: nếp gấp

Thí dụ

Dưới đây là một ví dụ về vimdiffviệc xtermso sánh hai phiên bản của cupstệp cấu hình:

nhập mô tả hình ảnh ở đây

Bạn có thể thấy rằng các phần dài của các dòng giống hệt nhau đã được thu gọn. Họ có thể được mở lại với zo.

Bảng màu sẽ thay đổi tùy thuộc vào cài đặt tùy chọn của bạn. Trong ví dụ trên, khi một dòng xuất hiện trong một tệp nhưng không phải là một tệp khác, dòng đó được đặt nền màu xanh đậm. Trong tệp khác, các dòng bị thiếu được biểu thị bằng các đường đứt nét. Khi một dòng xuất hiện trong cả hai tệp nhưng có một số khác biệt, các phần không thay đổi của dòng có nền màu hồng và các phần thay đổi có nền màu đỏ.


14

Trên FreeBSD hoặc hầu hết các hệ thống Linux, bạn có thể dẫn đầu ra của diff qua cat -v -e -tđể hiển thị các khác biệt về khoảng trắng.

diff file1 file2 | cat -vet

Các tab sẽ được hiển thị dưới dạng ^I, một $sẽ được hiển thị ở cuối mỗi dòng để bạn có thể thấy khoảng trắng ở cuối và các ký tự không in sẽ được hiển thị dưới dạng ^Xhoặc M-X.

Nếu bạn có GNU coreutils (có sẵn trên hầu hết các bản phân phối Linux không bận rộn), điều này có thể được đơn giản hóa thành

diff file1 file2 | cat -A

Trên các hệ thống busybox, sử dụng catv -vet.


2

Là một trong những tệp được chỉnh sửa trên máy Windows?

Chấm dứt dòng tiêu chuẩn trên Windows là CRLF, trong đó trên Linux, nó chỉ đơn giản là LF (và trên máy Mac, nó từng là CR, nhưng tôi nghi ngờ điều đó đã thay đổi kể từ OS X).

Hãy thử wc -ltrên các tệp và xem có bao nhiêu dòng, sau đó xem sự khác biệt kích thước có giống với số lượng dòng không (dòng cuối cùng có thể không bị chấm dứt trong một tệp).


Cảm ơn đã trả lời nhanh chóng. Thực hiện đếm số dòng cho thấy một tệp có thêm 5 dòng (tôi mong đợi điều này khi tôi thực hiện chỉnh sửa). Tôi đã nhận được một tệp từ máy Linux và tệp kia đã được kiểm tra từ kho lưu trữ mã trên Linux. Tôi tin rằng việc xem tệp có dấu kết thúc Windows trong vim sẽ hiển thị ký tự cuối cùng là ^ M và đó không phải là trường hợp.
Romski

3
vim thực sự đủ thông minh để tự động phát hiện chấm dứt dòng, xem stackoverflow.com/questions/3852868 để biết chi tiết.
hàng rào

Tôi đã không nhận thức được điều đó! Tôi sẽ kiểm tra lại
Romski 4/2/2015

2

odcó thể giúp. Lệnh Octal Dump có thể hiển thị nội dung ở dạng thập lục phân. Điều này có thể giúp bạn xem các byte nào, bao gồm byte rỗng hoặc khoảng trắng không mong muốn, có trong một tệp. Các nguyên nhân phổ biến có thể có thể là LF so với CRLF, các tab so với khoảng trắng hoặc ASCII so với Unicode (thường có thể có một byte rỗng trước mỗi byte hiển thị thông thường). od -x filenamephải tiết lộ bất kỳ mô hình nào. Nếu bạn muốn một cách phức tạp hơn để xem tệp, bất kỳ "trình soạn thảo hex" nào cũng có thể làm tốt. Điều thú vị odlà, giống như cutlệnh, nó được tích hợp vào nhiều hệ thống Unix. Vì vậy, thường xuyên, không cần cài đặt riêng biệt.

Nếu bạn cần các tệp giống nhau hơn, trcó thể thực hiện một số thay đổi và sedcó thể thực hiện nhiều hơn. Tôi có thể bắt đầu với ls -lviệc xem tệp nào lớn hơn, sau đó xem byte để xem những gì cần thay đổi, và sau đó thay đổi một trong các tệp để chúng có vẻ giống nhau hơn.


1

Để tìm ra nơi có khoảng trắng và tab thực sự, bạn có thể thay thế chúng bằng cách sử dụng sedví dụ:

$ 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

Và bây giờ so sánh hai tập tin.


Thậm chí tốt hơn, bạn có thể chạy bộ lọc đó trên đầu ra khác. Hoặc bạn có thể sử dụng bộ lọc được tạo sẵn trong cat, như trong superuser.com/a/913368/37154
clacke

0

Nội dung sau đây được sao chép ở đây từ phần "câu hỏi" ở trên, được viết bởi Romski.

Cả hai vimdiffdiff file1 file2 | cat -Arất hữu ích từ góc độ công cụ.

Cuối cùng, tôi tìm thấy một vấn đề nữa. Một số tệp của tôi được mã hóa bằng UTF-8 BOM. Điều này đã được đánh dấu bằng cách sử dụng diff file1 file2 | cat -A. Điều này biểu hiện như M-oM-;M-?ở phần đầu của tệp bị ảnh hưởng:

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

Trong khi có một số vấn đề, tôi đã liệt kê một số lệnh bên dưới cho những người cần dọn dẹp tệp của họ:

# 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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.