Anda pada dasarnya perlu membandingkan dua file, mengabaikan byte trailing dengan syarat. Tidak ada opsi 'diff' untuk melakukan ini - tetapi ada sejumlah cara yang bisa dilakukan (misalnya, hex diff juga muncul di benak Anda.)
Untuk menggunakan 'diff', Anda pada dasarnya harus memodifikasi file yang hilang baris baru di akhir file, dan kemudian membandingkan. Anda bisa membuat direktori sementara dengan file yang dimodifikasi, atau dengan sedikit scripting, itu bisa dilakukan dalam memori. (Mengenai yang lebih disukai tergantung pada preferensi, ukuran file, jumlah file ...)
Misalnya, berikut ini akan mengubah konten file (gunakan sed -i
untuk memodifikasi di tempat, ini hanya mencetak ke stdout) untuk menambahkan baris baru jika ada yang hilang (atau biarkan file tidak berubah jika sudah ada baris baru):
sed -e '$a\' file1.txt
Dan hanya untuk meninjau sintaks 'diff' (mengembalikan true berarti mereka sama, false berarti berbeda):
$ diff a/file1.txt b/file1.txt \
&& echo '** are same' || echo '** are different'
2c2
< eof
---
> eof
\ No newline at end of file
** are different
Verifikasi bahwa hanya spasi putih yang berbeda:
$ diff --ignore-all-space a/file1.txt b/file1.txt \
&& echo '** are same' || echo '** are different'
** are same
Dalam bash, kita dapat menggunakan 'sed' untuk memanipulasi konten file saat dilewatkan ke 'diff' (file asli tidak berubah):
$ diff <(sed -e '$a\' a/file1.txt) <(sed -e '$a\' b/file1.txt) \
&& echo '** are same' || echo '** are different'
** are same
Sekarang yang harus Anda lakukan adalah meniru diff -r
untuk membandingkan direktori secara rekursif. Jika membandingkan direktori a
dan b
, maka untuk semua file di a
(misalnya, a/dir1/dir2/file.txt
) turunkan path ke file di b
(misalnya, b/dir1/dir2/file.txt
) dan bandingkan:
$ for f in $( find a -type f )
> do
> diff <(sed -e '$a\' $f) <(sed -e '$a\' b/${f#*/})
> done
Versi yang sedikit lebih verbose:
$ for f in $( find a -type f )
> do
> f1=$f
> f2=b/${f#*/}
> echo "compare: $f1 $f2"
> diff <(sed -e '$a\' $f1) <(sed -e '$a\' $f2) \
> && echo '** are same' || echo '** are different'
> done && echo '** all are same' || echo '** all are different'
compare: a/file1.txt b/file1.txt
** are same
compare: a/file2.txt b/file2.txt
** are same
** all are same
sed -e '$a\'
sebenarnya dilakukannya? thxsed
, berikan-e
skrip / ekspresi ( ) berikut , yang cocok dengan akhir file ($
), dan lakukan tindakan "append" (a \), tetapi jangan sebutkan teks apa pun (tidak ada setelah `\`) yang masih akan menambahkan EOF / baris baru ke akhir file (hanya jika itu hilang).a\
.Saya memecahkan masalah dengan menambahkan baris baru ke masing-masing file dan mengabaikan baris kosong di diff (opsi
-B
). Solusi ini mungkin tidak cocok untuk kasus penggunaan Anda tetapi mungkin membantu orang lain:sumber
Pipa output
diff
kegrep
perintah yang menjatuhkan pesan yang tidak ingin Anda lihat.sumber
Pikirkan pendekatan yang berbeda juga, yang akan bekerja untuk file yang lebih besar (dan masih tidak menyalin atau memodifikasi file asli). Anda masih harus mengemulasi traversal direktori rekursif (dan ada sejumlah cara untuk melakukan itu), tetapi contoh ini tidak menggunakan 'sed', melainkan hanya membandingkan dua file, tidak termasuk byte terakhir, menggunakan
cmp
, misalnya,Masih mengulang semua file dalam direktori, dan untuk dua file a / file.txt dan b / file.txt, hitung ukuran file yang lebih besar, dan kurangi satu, lalu lakukan bilangan biner (
cmp
) menggunakan jumlah byte ini (juga dalam pesta):Looping file akan sama dengan jawaban yang lain menggunakan
sed
dandiff
.sumber
Jawabannya sederhana.
Pesan tentang baris baru yang hilang tidak dalam aliran output
diff
tetapi dalam aliran kesalahan. Jadi, bengkokkan itu ke nirwana dan kamu telah selesai untuk selamanyasumber
Ada bendera di diff commnad:
--strip-trailing-cr
yang melakukan persis seperti yang Anda mintasumber
/r/n
seperti/n
dan tidak ada hubungannya dengan ekstra/n
sebelum EOF.