Hasil dari dua file berbeda dengan switched baris mengatakan melewatkan baris yang sama dua kali

28

Saya mencoba untuk memahami perintah diff linux pada dua file yang garis-garisnya hanya permutasi satu sama lain tetapi tidak dapat grok output yang dihasilkannya. Perhatikan tiga perintah di bawah ini:

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

Dapatkah seseorang menjelaskan keluaran cryptic di atas dari diff.

  1. Mengapa tidak ada menyebutkan "jeruk" sama sekali dalam output?
  2. Apa 1d0dan apa 2a2artinya?

Saya mengerti dari jawaban ini bahwa:

"<" berarti baris tidak ada di file2 dan ">" berarti baris hilang di file1

TAPI itu tidak menjelaskan mengapa jeruk hilang dalam output.

Kutu buku
sumber
12
Karena orangesmerupakan bagian umum terbesar antara kedua file, jadi apa yang Anda dapatkan adalah cara terpendek untuk mengekspresikan perbedaan antara keduanya.
Stéphane Chazelas
10
Dan jika Anda ingin keluaran yang lebih mudah dibaca, gunakan diff -u file1 file2saja. Itu disebut format "unified diff". Format diff asli dimaksudkan untuk menjadi sangat kompak, tetapi diff unified dimaksudkan untuk menjadi lebih mudah dibaca.
godlygeek
4
@godlygeek Ataudiff -y file1 file2
user80551

Jawaban:

27

Untuk memahami laporan, ingatlah bahwa diffini adalah preskriptif, yang menjelaskan perubahan apa yang perlu dilakukan pada file pertama ( file1) agar sama dengan file kedua ( file2).

Secara khusus, din 1d0berarti delete dan ain 2a2berarti add .

Demikian:

  • 1d0berarti baris 1 harus dihapus di file1( apples). 0di 1d0baris 0 berarti di mana mereka akan muncul di file kedua ( file2) seandainya mereka tidak dihapus. Itu berarti ketika mengubah file2ke file1(mundur) menambahkan baris 1 file1setelah baris 0 dari file2.
  • 2a2berarti menambahkan baris kedua ( oranges) dari file2ke baris kedua sekarang file1(setelah menghapus baris pertama file1, orangesberalih ke baris 1)
kekacauan
sumber
apa yang ada 0di dalam 1d0?
Geek
@Geek lihat hasil edit saya
chaos
1
@Geek Tapi hati-hati, itu bisa membuat simpul di otak =)
kekacauan
yang sudah, memang mulai membuat simpul :-)
Geek
13

Pertimbangkan file-file ini:

file1:

# cat file1
apples
pears
oranges
peaches

file2:

# cat file2
oranges
apples
peaches
ananas
banana

Bagaimana cara diffkerjanya, mengingat itu berdasarkan pesanan:

  1. diffmembaca blok pertama dari garis file1dan file2, dan mencoba menemukan garis yang sama:

      file1        file2        differences on left (<) or right side (>)
      apples                   <apples
      pears                    <pears 
      -------------------------------
    ->oranges    ->oranges
      peaches      apples
                   peaches
                   ananas
                   banana
    
  2. Sekarang akan melewati semua baris yang sama di kedua file, yang hanya orangesdalam kasus ini:

      file1        file2        differences on left (<) or right side (>)
      apples                   <apples
      pears                    <pears 
      oranges      oranges
      -------------------------------
    ->peaches    ->apples
                   peaches
                   ananas
                   banana
    
  3. Sekarang temukan satu set garis yang sama dan cetak perbedaan:

      file1        file2        differences on left (<) or right side (>)
      apples                   <apples
      pears                    <pears 
      oranges      oranges
                   apples      >apples
      -------------------------------
    ->peaches    ->peaches
                   ananas
                   banana
    
  4. Lewati garis yang sama

      file1        file2        differences on left (<) or right side (>)
      apples                   <apples
      pears                    <pears 
      oranges      oranges
                   apples      >apples
      peaches      peaches
      -------------------------------
    ->           ->ananas
                   banana
    
  5. Temukan garis yang identik, jika mungkin, dan cetak perbedaan:

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

Sekarang jika saya lakukan diff file1 file2:

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

Sekarang mudah untuk menjelaskan apa diffartinya output:

Agar file1setara dengan file2:

  • 1,2d0: Hapus ( d) baris 1-2dari file1dan memodifikasi garis 0dari file2sesuai
  • 3a2: Append ( a) dengan garis 3dari file1garis 2darifile2
  • 4a4,5: Append untuk berbaris 4dari file1garis 4-5darifile2

diffmembandingkan file1dengan file2baris demi baris dan menyelesaikan perbedaan dalam memori sementara. Setelah membuat file1 sama dengan file2 sampai kemunculan pertama suatu garis dalam file1, yang juga terjadi pada file2, semua garis yang sama sampai suatu perbedaan tidak disebutkan, sering diindikasikan sebagai ---. Dalam hal ini hanya ada satu baris yang sama, yaitu oranges. Perhatikan bahwa saya katakan file1sama dengan file2, sehingga file1dipandang relatif file2dan bukan sebaliknya.

Output dalam kaitannya dengan file pertama yang diberikan, dalam hal ini file1.

polym
sumber
2
Saya tidak suka penjelasan awal: applesterjadi di kedua file juga.
ATAU Mapper
1
@ORMapper Saya mengubah penjelasannya. Apakah ini terdengar lebih jelas / lebih baik sekarang :)?
polym
Tidak cukup, untuk sekarang Anda menulis "hanya ada satu baris yang sama, yaitu oranges". Salah: Sebenarnya ada dua garis, yang tidak hanya mirip , tetapi juga identik . Salah satu dari mereka membaca oranges, yang lain membaca apples. Juga, penjelasan Anda (murni berdasarkan pesanan) bertentangan dengan komentar Stéphane tentang pertanyaan (berdasarkan panjang) - siapa yang benar?
ATAU Mapper
@ORMapper Anda lupa "Dalam hal ini" dan baris sebelumnya. Maksud saya, pada langkah ini hanya ada satu baris yang sama. Saya hanya akan menambahkan contoh pada jawaban saya sehingga bisa dipahami dengan lebih baik.
Polym
1
@ORMapper Juga dapatkah Anda memberi saya contoh yang menunjukkan bahwa jawaban berbasis panjang sudah benar?
polym
8

Mereka disana:

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

Format output standar (lama) akan menampilkan perbedaan antara file tanpa teks di sekitarnya dengan area di mana file berbeda.

Misalnya: 1d0 <(hapus) berarti apel harus dihapus dari baris pertama file1, dan 2a2 >(tambahkan) berarti apel harus ditambahkan ke file2baris kedua, sehingga kedua file dapat dicocokkan.

Dokumentasi tersedia di info diffmenjelaskan lebih lanjut:

Menampilkan Perbedaan Tanpa Konteks

diffFormat output "normal" menunjukkan setiap potongan perbedaan tanpa konteks sekitarnya. Kadang-kadang output seperti itu adalah cara yang paling jelas untuk melihat bagaimana garis telah berubah, tanpa kekacauan dari garis terdekat yang tidak berubah (walaupun Anda bisa mendapatkan hasil yang serupa dengan konteks atau format yang disatukan dengan menggunakan 0 baris konteks). Namun, format ini tidak lagi banyak digunakan untuk mengirim tambalan; untuk tujuan itu, format konteks dan format terpadu lebih unggul. Format normal adalah standar untuk kompatibilitas dengan versi lama diffdan standar POSIX. Gunakan --normalopsi untuk memilih format output ini secara eksplisit.

Penjelasan terperinci tentang Format Normal

Format output normal terdiri dari satu atau lebih rongsokan perbedaan; setiap bingkah menunjukkan satu area di mana file berbeda. Bakhil format normal terlihat seperti ini:

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

Ada tiga jenis perintah perubahan. Masing-masing terdiri dari nomor baris atau rentang baris yang dipisahkan koma di file pertama, karakter tunggal yang menunjukkan jenis perubahan yang akan dibuat, dan nomor baris atau rentang baris yang dipisahkan koma di file kedua. Semua nomor baris adalah nomor baris asli di setiap file. Jenis-jenis perintah perubahan adalah:

LaR Tambahkan baris dalam rentang R dari file kedua setelah baris L dari file pertama. Misalnya, 8a12,15berarti menambahkan baris 12-15 dari file 2 setelah baris 8 dari file 1; atau, jika mengubah file 2 menjadi file 1, hapus baris 12-15 dari file 2.

FcT Ganti baris dalam rentang F dari file pertama dengan baris dalam rentang T dari file kedua. Ini seperti gabungan tambah dan hapus, tetapi lebih ringkas. Sebagai contoh, 5,7c8,10berarti mengubah baris 5-7 dari file 1 untuk dibaca sebagai baris 8-10 dari file 2; atau, jika mengubah file 2 menjadi file 1, ubah baris 8-10 dari file 2 untuk dibaca sebagai baris 5-7 dari file 1.

RdL Hapus baris dalam rentang R dari file pertama; baris L adalah tempat mereka muncul di file kedua seandainya mereka tidak dihapus. Misalnya, 5,7d3berarti menghapus baris 5-7 dari file 1; atau, jika mengubah file 2 menjadi file 1, tambahkan baris 5-7 dari file 1 setelah baris 3 dari file 2.

Lihat juga:


Jadi untuk melihat jeruk, Anda harus membuatnya berdampingan atau dengan menggunakan konteks terpadu.

Sebagai contoh:

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

$ diff -u file1 file2
@@ -1,2 +1,2 @@
-apples
 oranges
+apples
kenorb
sumber