Kết quả của diff hai tập tin với các dòng chuyển đổi nói rằng thiếu cùng một dòng hai lần


28

Tôi đang cố gắng để hiểu lệnh diff của linux trên hai tệp có các dòng chỉ là hoán vị của nhau nhưng không thể dò tìm đầu ra mà nó tạo ra. Hãy xem xét ba lệnh dưới đây:

[myPrompt]$ cat file1
apples
oranges
[myPrompt]$ cat file2 
oranges
apples
[myPrompt]$ diff file1 file2
1d0
< apples
2a2
> apples

Ai đó có thể giải thích đầu ra mật mã ở trên từ diff.

  1. Tại sao không có đề cập đến "cam" ở đầu ra?
  2. Không gì 1d02a2nghĩa là gì?

Tôi hiểu từ câu trả lời này rằng:

"<" có nghĩa là dòng bị thiếu trong tệp2 và ">" có nghĩa là dòng bị thiếu trong tệp1

NHƯNG điều đó không giải thích tại sao cam bị thiếu trong đầu ra.


12
Bởi vì orangeslà phần chung lớn nhất giữa hai tệp, vì vậy những gì bạn có được là cách ngắn nhất để thể hiện sự khác biệt giữa hai tệp.
Stéphane Chazelas

10
Và nếu bạn muốn đầu ra dễ đọc hơn, chỉ cần sử dụng diff -u file1 file2thay thế. Đó gọi là định dạng "unified diff". Định dạng khác ban đầu có nghĩa là rất nhỏ gọn, nhưng khác biệt thống nhất có nghĩa là dễ đọc hơn nhiều.
trời ơi

4
@godlygeek Hoặcdiff -y file1 file2
user80551

Câu trả lời:


27

Để hiểu báo cáo, hãy nhớ đó difflà quy định, mô tả những thay đổi cần được thực hiện đối với tệp đầu tiên ( file1) để làm cho nó giống với tệp thứ hai ( file2).

Cụ thể, din 1d0có nghĩa là xóaain 2a2có nghĩa là thêm .

Như vậy:

  • 1d0có nghĩa là dòng 1 phải bị xóa trong file1( apples). 0trong 1d0phương tiện, dòng 0 là nơi chúng sẽ xuất hiện trong tệp thứ hai ( file2) nếu chúng không bị xóa. Điều đó có nghĩa là khi thay đổi file2thành file1(ngược) nối thêm dòng 1 file1sau dòng 0 của file2.
  • 2a2có nghĩa là nối dòng thứ hai ( oranges) từ file2dòng thứ hai bây giờ file1(sau khi xóa dòng thứ nhất vào file1, orangeschuyển sang dòng 1)

những gì là 0trong 1d0?
Geek

@Geek xem bản chỉnh sửa của tôi
hỗn loạn

1
@Geek Nhưng hãy cẩn thận, điều đó có thể tạo ra các nút thắt trong não =)
hỗn loạn

điều đó thực sự đã bắt đầu tạo ra các nút thắt :-)
Geek

13

Hãy xem xét các tệp này:

file1:

# cat file1
apples
pears
oranges
peaches

file2:

# cat file2
oranges
apples
peaches
ananas
banana

Làm thế nào diffhoạt động, cho nó là dựa trên thứ tự:

  1. diffđọc khối đầu tiên của dòng file1file2, và cố gắng tìm các dòng bằng nhau:

      file1        file2        differences on left (<) or right side (>)
      apples                   <apples
      pears                    <pears 
      -------------------------------
    ->oranges    ->oranges
      peaches      apples
                   peaches
                   ananas
                   banana
    
  2. Bây giờ nó sẽ bỏ qua tất cả các dòng bằng nhau trong cả hai tệp, chỉ orangestrong trường hợp này:

      file1        file2        differences on left (<) or right side (>)
      apples                   <apples
      pears                    <pears 
      oranges      oranges
      -------------------------------
    ->peaches    ->apples
                   peaches
                   ananas
                   banana
    
  3. Bây giờ tìm một tập hợp các dòng tương tự và in ra sự khác biệt:

      file1        file2        differences on left (<) or right side (>)
      apples                   <apples
      pears                    <pears 
      oranges      oranges
                   apples      >apples
      -------------------------------
    ->peaches    ->peaches
                   ananas
                   banana
    
  4. Bỏ qua các dòng tương tự

      file1        file2        differences on left (<) or right side (>)
      apples                   <apples
      pears                    <pears 
      oranges      oranges
                   apples      >apples
      peaches      peaches
      -------------------------------
    ->           ->ananas
                   banana
    
  5. Tìm các dòng giống hệt nhau, nếu có thể và in các khác biệt:

    line_file1    file1    line_file2    file2        differences on left (<) or right side (>)
             1    apples                              <apples 
             2    pears                               <pears 
             3    oranges           1    oranges
                                    2    apples       >apples
             4    peaches           3    peaches
                                    4    ananas       >ananas
                                    5    banana       >banana
             -----------------------------------------------
    

Bây giờ nếu tôi làm diff file1 file2:

# diff file1 file2
1,2d0
< apples
< pears
3a2
> apples
4a4,5
> ananas
> banana

Bây giờ thật đơn giản để giải thích diffđầu ra của nó có nghĩa là gì:

Để làm cho file1bằng file2:

  • 1,2d0: Xóad dòng ( ) 1-2khỏi file1và sửa đổi dòng 0cho file2phù hợp
  • 3a2: Nối ( a) để dòng 3của file1dòng 2củafile2
  • 4a4,5: Nối để dòng 4của file1dòng 4-5củafile2

diffso sánh file1với file2từng dòng và giải quyết sự khác biệt trong bộ nhớ tạm thời. Sau khi thực hiện file1 bằng cho file2 đến khi xuất hiện lần đầu tiên của một dòng file1, cũng xảy ra file2, tất cả các dòng bằng nhau cho đến khi một sự khác biệt không được đề cập, thường được chỉ định là ---. Trong trường hợp này chỉ có một dòng tương tự, đó là oranges. Lưu ý rằng tôi đã nói file1bằng file2, vì vậy file1được xem tương đối file2và không phải là cách khác.

Đầu ra liên quan đến tập tin đầu tiên được đưa ra, trong trường hợp này file1.


2
Tôi không thích lời giải thích ban đầu: cũng applesxảy ra trong cả hai tập tin.
HOẶC Mapper

1
@ORMapper Tôi đã thay đổi lời giải thích. Nghe có vẻ rõ ràng hơn / tốt hơn bây giờ :)?
polym

Không hẳn, bây giờ bạn đã viết "chỉ có một dòng tương tự oranges". Sai: Thực tế có hai dòng, không chỉ giống nhau , mà hoàn toàn giống nhau . Một trong số họ đọc oranges, một người khác đọc apples. Ngoài ra, lời giải thích của bạn (hoàn toàn dựa trên thứ tự) trái ngược với nhận xét của Stéphane về câu hỏi (dựa trên độ dài) - ai đúng?
HOẶC Mapper

@ORMapper Bạn đã quên "Trong trường hợp này" và các dòng trước đó. Tôi có nghĩa là trong bước này chỉ có một dòng tương tự. Tôi sẽ chỉ thêm một ví dụ cho câu trả lời của tôi để nó có thể được hiểu rõ hơn.
polym

1
@ORMapper Bạn cũng có thể cho tôi một ví dụ cho thấy câu trả lời dựa trên độ dài là chính xác?
polym

8

Họ đây rồi:

$ diff file1 file2
1d0
< apples
2a2
> apples
$ diff file2 file1
1d0
< oranges
2a2
> oranges

8

Định dạng đầu ra tiêu chuẩn (cũ) sẽ hiển thị sự khác biệt giữa các tệp mà không có văn bản xung quanh với các khu vực nơi các tệp khác nhau.

Ví dụ: 1d0 <(xóa) có nghĩa là táo cần được xóa khỏi dòng thứ nhất file12a2 >(chắp thêm) có nghĩa là táo cần được thêm vào file2trên dòng thứ 2, vì vậy cả hai tệp có thể được khớp.

Tài liệu có sẵn tại info diffgiải thích thêm.

Hiển thị sự khác biệt mà không có bối cảnh

diffĐịnh dạng đầu ra "bình thường" hiển thị từng khối khác biệt mà không có bất kỳ bối cảnh xung quanh. Đôi khi đầu ra như vậy là cách rõ ràng nhất để xem các dòng đã thay đổi như thế nào, mà không có sự lộn xộn của các dòng không thay đổi gần đó (mặc dù bạn có thể nhận được kết quả tương tự với bối cảnh hoặc các định dạng hợp nhất bằng cách sử dụng 0 dòng ngữ cảnh). Tuy nhiên, định dạng này không còn được sử dụng rộng rãi để gửi các bản vá; cho mục đích đó, định dạng ngữ cảnh và định dạng thống nhất là vượt trội. Định dạng thông thường là mặc định để tương thích với các phiên bản cũ hơn diffvà tiêu chuẩn POSIX. Sử dụng --normaltùy chọn để chọn định dạng đầu ra này một cách rõ ràng.

Mô tả chi tiết về định dạng bình thường

Định dạng đầu ra bình thường bao gồm một hoặc nhiều khối khác nhau; mỗi hunk hiển thị một khu vực nơi các tập tin khác nhau. Hunk định dạng bình thường trông như thế này:

 CHANGE-COMMAND
 < FROM-FILE-LINE
 < FROM-FILE-LINE...
 ---
 > TO-FILE-LINE
 > TO-FILE-LINE...

Có ba loại lệnh thay đổi. Mỗi dòng bao gồm một số dòng hoặc phạm vi dòng được phân tách bằng dấu phẩy trong tệp đầu tiên, một ký tự duy nhất cho biết loại thay đổi cần thực hiện và số dòng hoặc phạm vi dòng được phân tách bằng dấu phẩy trong tệp thứ hai. Tất cả các số dòng là số dòng gốc trong mỗi tệp. Các loại lệnh thay đổi là:

LaR Thêm các dòng trong phạm vi R của tệp thứ hai sau dòng L của tệp đầu tiên. Ví dụ: 8a12,15có nghĩa là nối các dòng 12-15 của tệp 2 sau dòng 8 của tệp 1; hoặc, nếu thay đổi tệp 2 thành tệp 1, hãy xóa các dòng 12-15 của tệp 2.

FcT Thay thế các dòng trong phạm vi F của tệp đầu tiên bằng các dòng trong phạm vi T của tệp thứ hai. Điều này giống như một kết hợp thêm và xóa, nhưng nhỏ gọn hơn. Ví dụ: 5,7c8,10có nghĩa là thay đổi dòng 5-7 của tệp 1 để đọc thành dòng 8-10 của tệp 2; hoặc, nếu thay đổi tệp 2 thành tệp 1, hãy thay đổi dòng 8-10 của tệp 2 để đọc thành dòng 5-7 của tệp 1.

RdL Xóa các dòng trong phạm vi R từ tệp đầu tiên; dòng L là nơi chúng sẽ xuất hiện trong tệp thứ hai nếu chúng không bị xóa. Ví dụ: 5,7d3có nghĩa là xóa các dòng 5-7 của tệp 1; hoặc, nếu thay đổi tệp 2 thành tệp 1, hãy nối các dòng 5-7 của tệp 1 sau dòng 3 của tệp 2.

Xem thêm:


Vì vậy, để nhìn thấy cam, bạn sẽ phải phân biệt nó cạnh nhau hoặc bằng cách sử dụng bối cảnh thống nhất.

Trong ví dụ:

$ diff -y file1 file2
apples                                <
oranges                             oranges
                                  > apples

$ diff -u file1 file2
@@ -1,2 +1,2 @@
-apples
 oranges
+apples
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.