ผลลัพธ์ของ diff สองไฟล์ที่มีสวิตช์สลับบอกว่าไม่มีบรรทัดเดียวกันสองครั้ง


28

ฉันพยายามที่จะเข้าใจคำสั่ง linux diff ในสองไฟล์ที่บรรทัดมีการเรียงสับเปลี่ยนกัน แต่ไม่สามารถติดตามผลลัพธ์ที่สร้างขึ้นได้ พิจารณาสามคำสั่งด้านล่าง:

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

บางคนสามารถอธิบายเอาต์พุตที่เป็นความลับดังกล่าวจาก diff

  1. ทำไมไม่มีการกล่าวถึง "ส้ม" เลยในเอาต์พุต
  2. อะไร1d0และ2a2หมายความว่าอย่างไร

ฉันเข้าใจ จากคำตอบนี้ว่า:

"<" หมายถึงบรรทัดนั้นหายไปใน file2 และ ">" หมายถึงบรรทัดนั้นขาดหายไปใน file1

แต่นั่นไม่ได้อธิบายว่าทำไมส้มจึงหายไปในผลลัพธ์


12
เนื่องจากorangesเป็นส่วนที่ใหญ่ที่สุดระหว่างสองไฟล์ดังนั้นสิ่งที่คุณได้รับคือวิธีที่สั้นที่สุดในการแสดงความแตกต่างระหว่างสองไฟล์
Stéphane Chazelas

10
และถ้าคุณต้องการเอาต์พุตที่อ่านได้มากกว่าให้ใช้diff -u file1 file2แทน นั่นคือรูปแบบที่เรียกว่า "unified diff" รูปแบบ diff ต้นฉบับหมายถึงมีขนาดกะทัดรัดมาก แต่ diffs แบบรวมจะถูกอ่านได้มากขึ้น
godlygeek

4
@godlygeek Ordiff -y file1 file2
user80551

คำตอบ:


27

เพื่อทำความเข้าใจกับรายงานโปรดจำไว้ว่าdiffเป็นแบบกำหนดอธิบายการเปลี่ยนแปลงใดที่จำเป็นต้องทำกับไฟล์แรก ( file1) เพื่อทำให้มันเหมือนกับไฟล์ที่สอง (file2 )

โดยเฉพาะการdin 1d0หมายถึงการลบและain 2a2หมายถึงการเพิ่มเพิ่ม

ดังนั้น:

  • 1d0หมายความว่าต้องลบบรรทัด 1 ในfile1( apples) 0ในความ1d0หมายบรรทัด 0 เป็นที่ที่พวกเขาจะปรากฏในไฟล์ที่สอง ( file2) หากพวกเขาจะไม่ถูกลบ ซึ่งหมายความว่าเมื่อเปลี่ยนfile2เป็นfile1(ย้อนหลัง) ต่อท้ายบรรทัด 1 จากfile1หลังบรรทัด 0 ของfile2ของ
  • 2a2วิธีการผนวกบรรทัดที่สอง ( oranges) จากfile2ไปยังบรรทัดตอนที่สองของfile1(หลังจากลบบรรทัดแรกในfile1, orangesเปลี่ยนไปสาย 1)

สิ่งที่อยู่0ใน1d0?
Geek

@ Geek ดูการแก้ไขของฉัน
ความสับสนวุ่นวาย

1
@Geek แต่ต้องระวังที่สามารถทำให้นอตในสมอง =)
ความวุ่นวาย

ที่มีการเริ่มต้นทำแน่นอนนอต :-)
Geek

13

พิจารณาไฟล์เหล่านี้:

file1:

# cat file1
apples
pears
oranges
peaches

file2:

# cat file2
oranges
apples
peaches
ananas
banana

วิธีการdiffทำงานให้เป็นไปตามคำสั่ง:

  1. diffอ่านบล็อกแรกของบรรทัดของfile1และfile2และพยายามค้นหาบรรทัดที่เท่ากัน:

      file1        file2        differences on left (<) or right side (>)
      apples                   <apples
      pears                    <pears 
      -------------------------------
    ->oranges    ->oranges
      peaches      apples
                   peaches
                   ananas
                   banana
    
  2. ตอนนี้มันจะข้ามทุกบรรทัดที่เท่ากันในทั้งสองไฟล์ซึ่งเป็นเพียงorangesในกรณีนี้:

      file1        file2        differences on left (<) or right side (>)
      apples                   <apples
      pears                    <pears 
      oranges      oranges
      -------------------------------
    ->peaches    ->apples
                   peaches
                   ananas
                   banana
    
  3. ตอนนี้ค้นหาชุดของบรรทัดที่คล้ายกันอีกชุดและพิมพ์ความแตกต่าง

      file1        file2        differences on left (<) or right side (>)
      apples                   <apples
      pears                    <pears 
      oranges      oranges
                   apples      >apples
      -------------------------------
    ->peaches    ->peaches
                   ananas
                   banana
    
  4. ข้ามเส้นที่คล้ายกัน

      file1        file2        differences on left (<) or right side (>)
      apples                   <apples
      pears                    <pears 
      oranges      oranges
                   apples      >apples
      peaches      peaches
      -------------------------------
    ->           ->ananas
                   banana
    
  5. ค้นหาบรรทัดที่เหมือนกันถ้าเป็นไปได้และพิมพ์ความแตกต่าง:

    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
             -----------------------------------------------
    

ตอนนี้ถ้าฉันทำdiff file1 file2:

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

ตอนนี้มันง่ายที่จะอธิบายสิ่งที่ diffหมายของผลลัพธ์:

เพื่อให้file1เท่ากับfile2:

  • 1,2d0: ลบ ( d) สาย1-2จากfile1และปรับเปลี่ยนสาย0ของfile2ตาม
  • 3a2: ผนวก ( a) กับสาย3ของfile1สาย2ของfile2
  • 4a4,5: ผนวกกับสาย4ของfile1สาย4-5ของfile2

diffเปรียบเทียบfile1กับfile2บรรทัดต่อบรรทัดและตัดสินความแตกต่างในหน่วยความจำชั่วคราว หลังจากทำการfile1 เท่ากับ file2จนกว่าจะเกิดขึ้นครั้งแรกของสายในfile1ซึ่งยังเกิดขึ้นในทุกสายที่มีค่าเท่ากันขึ้นจนความแตกต่างที่ไม่ได้กล่าวถึงมักจะแสดงเป็นfile2 ในกรณีนี้มีเพียงหนึ่งบรรทัดที่คล้ายกันซึ่งเป็น--- orangesโปรดทราบว่าฉันพูดว่าfile1เท่ากันfile2ดังนั้นจึงfile1มีการดูที่เกี่ยวข้องfile2และไม่ใช่วิธีอื่น ๆ

เอาต์พุตมีความสัมพันธ์กับไฟล์แรกที่กำหนดในกรณีfile1นี้


2
ฉันไม่ชอบคำอธิบายเริ่มต้น: applesเกิดขึ้นในไฟล์ทั้งสองเช่นกัน
หรือผู้ทำแผนที่

1
@ ปกติฉันเปลี่ยนคำอธิบาย เสียงชัดเจนขึ้นหรือดีขึ้นตอนนี้ :)?
polym

ไม่มากสำหรับตอนนี้คุณเขียนว่า "มีเพียงหนึ่งบรรทัดที่คล้ายกันซึ่งก็คือoranges" ผิด: มีสองบรรทัดจริง ๆซึ่งไม่เพียง แต่คล้ายกันแต่เหมือนกันทุกประการ หนึ่งของพวกเขาอ่านอีกคนหนึ่งอ่านoranges applesนอกจากนี้คำอธิบายของคุณ (อิงตามคำสั่งล้วน) นั้นขัดแย้งกับความคิดเห็นของStéphaneในคำถาม (ตามความยาว) - ใครถูกต้อง?
หรือผู้ทำแผนที่

@ ปกติคุณลืม "ในกรณีนี้" และบรรทัดก่อนหน้านั้น ฉันหมายถึงมันในขั้นตอนนี้มีเพียงหนึ่งบรรทัดที่คล้ายกัน ฉันจะเพิ่มตัวอย่างในคำตอบเพื่อให้สามารถเข้าใจได้ดีขึ้น
polym

1
@ORMapper คุณสามารถยกตัวอย่างที่แสดงว่าคำตอบตามความยาวนั้นถูกต้องหรือไม่
polym


8

รูปแบบเอาต์พุตมาตรฐาน (เก่า) จะแสดงความแตกต่างระหว่างไฟล์โดยไม่มีข้อความล้อมรอบด้วยพื้นที่ที่ไฟล์ต่างกัน

ตัวอย่างเช่น: 1d0 <(ลบ) หมายถึงแอปเปิ้ลจะต้องถูกลบออกจากบรรทัดที่ 1 ของfile1และ2a2 >(ผนวก) หมายถึงแอปเปิ้ลจะต้องเพิ่มลงในfile2ในบรรทัดที่ 2 เพื่อให้ทั้งสองไฟล์สามารถจับคู่

เอกสารinfo diffอธิบายเพิ่มเติมได้ที่:

แสดงความแตกต่างโดยไม่มีบริบท

diffรูปแบบเอาต์พุต"ปกติ" แสดงความแตกต่างแต่ละก้อนโดยไม่มีบริบทแวดล้อม บางครั้งเอาต์พุตดังกล่าวเป็นวิธีที่ชัดเจนที่สุดในการดูว่าบรรทัดมีการเปลี่ยนแปลงอย่างไรโดยไม่ต้องยุ่งเหยิงของบรรทัดที่ไม่เปลี่ยนแปลงในบริเวณใกล้เคียง (แม้ว่าคุณจะได้ผลลัพธ์ที่คล้ายกันกับบริบทหรือรูปแบบรวมโดยใช้บริบท 0 บรรทัด) อย่างไรก็ตามรูปแบบนี้ไม่ได้ใช้กันอย่างแพร่หลายในการส่งแพตช์ สำหรับวัตถุประสงค์นั้นรูปแบบบริบทและรูปแบบรวมจะดีกว่า รูปแบบปกติเป็นค่าเริ่มต้นสำหรับความเข้ากันได้กับรุ่นเก่ากว่าdiffและมาตรฐาน POSIX ใช้--normalตัวเลือกเพื่อเลือกรูปแบบผลลัพธ์นี้อย่างชัดเจน

คำอธิบายโดยละเอียดของรูปแบบปกติ

รูปแบบเอาต์พุตปกติประกอบด้วยความแตกต่างอย่างน้อยหนึ่งอย่าง ก้อนใหญ่แต่ละอันจะแสดงพื้นที่หนึ่งที่ไฟล์ต่างกัน รูปแบบปกติ hunks มีลักษณะเช่นนี้:

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

คำสั่งการเปลี่ยนแปลงมีสามประเภท แต่ละประกอบด้วยหมายเลขบรรทัดหรือช่วงของบรรทัดที่คั่นด้วยเครื่องหมายจุลภาคในไฟล์แรกอักขระเดียวที่ระบุชนิดของการเปลี่ยนแปลงที่จะทำและหมายเลขบรรทัดหรือช่วงที่คั่นด้วยเครื่องหมายจุลภาคในไฟล์ที่สอง หมายเลขบรรทัดทั้งหมดเป็นหมายเลขบรรทัดดั้งเดิมในแต่ละไฟล์ ประเภทของคำสั่งการเปลี่ยนแปลงคือ:

LaR เพิ่มบรรทัดในช่วง R ของไฟล์ที่สองหลังจากบรรทัด L ของไฟล์แรก ตัวอย่างเช่น,8a12,15หมายถึงการผนวกบรรทัดที่ 12-15 ของไฟล์ 2 หลังจากบรรทัดที่ 8 ของไฟล์ 1 หรือหากเปลี่ยนไฟล์ 2 เป็นไฟล์ 1 ให้ลบบรรทัด 12-15 ของไฟล์ 2

FcT แทนที่บรรทัดในช่วง F ของไฟล์แรกด้วยบรรทัดในช่วง T ของไฟล์ที่สอง นี่เป็นเหมือนการเพิ่มและลบแบบรวม ตัวอย่างเช่น,5,7c8,10หมายถึงเปลี่ยนบรรทัด 5-7 ของไฟล์ 1 เพื่ออ่านเป็นบรรทัด 8-10 ของไฟล์ 2 หรือหากเปลี่ยนไฟล์ 2 เป็นไฟล์ 1 ให้เปลี่ยนบรรทัด 8-10 ของไฟล์ 2 เพื่ออ่านเป็นบรรทัด 5-7 ของไฟล์ 1

RdL ลบบรรทัดในช่วง R จากไฟล์แรก; บรรทัด L คือตำแหน่งที่ปรากฏในไฟล์ที่สองหากไม่ถูกลบ ตัวอย่างเช่น5,7d3หมายถึงลบบรรทัด 5-7 ของไฟล์ 1; หรือหากเปลี่ยนไฟล์ 2 เป็นไฟล์ 1 ให้ต่อท้ายบรรทัดที่ 5-7 ของไฟล์ 1 ต่อจากบรรทัดที่ 3 ของไฟล์ 2

ดูสิ่งนี้ด้วย:


ดังนั้นเพื่อดูส้มคุณจะต้องแยกมันทีละข้างหรือโดยใช้บริบทแบบรวม

ในตัวอย่าง:

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

$ diff -u file1 file2
@@ -1,2 +1,2 @@
-apples
 oranges
+apples
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.