Bagaimana membandingkan dua file berbeda baris demi baris di unix?

13

File1:

123
234
345
456

File2:

123
234
343
758

Output yang diharapkan: File3:

TRUE
TRUE
FALSE
FALSE

jadi kode harus membandingkan dua file dan mencetak 'BENAR' jika cocok jika tidak maka akan mencetak 'SALAH' dalam file baru. Adakah yang bisa memberikan solusi untuk ini?

Velu
sumber
10
Apa yang terjadi jika kedua file memiliki panjang yang tidak sama? Bagian mana dari solusi masalah ini yang bermasalah?
Kusalananda
9
Anda mungkin ingin melihatnya diff.
Panki
2
Perintah lain yang bermanfaat dalam situasi ini adalah comm. Itu membuatnya mudah untuk membuat daftar baris yang memiliki kedua file yang sama atau unik untuk satu atau yang lain.
Giacomo Alzetta
1
@ GiacomoAlzetta Masalahnya commadalah membutuhkan input yang diurutkan. Terlepas dari kenyataan bahwa contoh dalam pertanyaan memang telah mengurutkan input, pertanyaan itu tidak pernah menegaskan bahwa ini adalah data aktual yang sedang digunakan dan tidak pernah mengatakan apa-apa tentang pemesanan data.
Kusalananda
2
Trik αғsнιη nlberguna communtuk memaksakan pengurutan pada file.
glenn jackman

Jawaban:

56

Gunakan diffperintah sebagai berikut, di bashatau shell lain yang mendukung <(...) proses penggantian atau Anda dapat meniru seperti yang ditunjukkan di sini :

diff --new-line-format='FALSE'$'\n' \
     --old-line-format='' \
     --unchanged-line-format='TRUE'$'\n' \
<(nl file1) <(nl file2)

Output akan menjadi:

TRUE
TRUE
FALSE
FALSE

--new-line-format='FALSE'$'\n, cetak FALSEjika baris berbeda dan dengan --old-line-format=''kami menonaktifkan output jika baris berbeda untuk file1 yang dikenal sebagai file lama ke perintah berbeda (Kita bisa menukar ini juga, yang berarti bahwa salah satu dari mereka harus mencetak yang FALSElain harus dinonaktifkan.)

--unchanged-line-format='TRUE'$'\n', cetak TRUEjika garis-garisnya sama. yang $'\n'C-gaya melarikan diri sintaks digunakan untuk mencetak baris baru setelah setiap output baris.

αғsнιη
sumber
24

Dengan asumsi file tidak mengandung karakter tab:

$ paste file1 file2 | awk -F '\t' '{ print ($1 == $2 ? "TRUE" : "FALSE") }'
TRUE
TRUE
FALSE
FALSE

Ini digunakan pasteuntuk membuat dua kolom tab-dibatasi, dengan isi dari dua file di kolom mana pun. The awkperintah membandingkan dua kolom pada setiap baris dan mencetak TRUEjika kolom yang sama dan sebaliknya cetakan FALSE.

Kusalananda
sumber
10

Dengan asumsi kedua file memiliki jumlah baris yang sama:

awk '{getline f2 < "file2"; print f2 == $0 ? "TRUE" : "FALSE"}' file1

Itu melakukan perbandingan numerik jika string untuk membandingkan adalah angka dan leksikal sebaliknya. Misalnya, 100dan 1.0e2akan dianggap identik. Mengubahf2"" == $0 memaksa perbandingan leksikal dalam hal apa pun.

Bergantung pada awkimplementasinya, perbandingan leksikal akan dilakukan seolah-olah dengan menggunakan memcmp()(perbandingan byte-ke-byte) atau seolah-olah dengan menggunakan strcoll()(apakah kedua string mengurutkan yang sama dalam urutan pengumpulan lokal). Itu dapat membuat perbedaan di beberapa lokal di mana urutan tidak didefinisikan dengan benar untuk beberapa karakter, tidak pada semua input angka desimal seperti dalam sampel Anda.

Stéphane Chazelas
sumber
7

Python 3

with open('file1') as file1, open('file2') as file2:
    for line1, line2 in zip(file1, file2):
        print(line1 == line2)

Keluaran:

True
True
False
False

Jika Anda membutuhkan TRUEdan FALSEdalam huruf besar, ganti garis cetak dengan salah satu dari ini:

print(str(line1 == line2).upper())
print('TRUE' if line1 == line2 else 'FALSE')
wjandrea
sumber
2
Dalam Python 2, melakukan import itertoolspertama, dan kemudian menggunakan itertools.izipbukannya zip. Kalau tidak, itu akan membaca kedua file ke memori, mungkin menggunakan terlalu banyak memori.
Poin
4

Dalam bash, membaca dari setiap file dalam satu whilelingkaran, membandingkan garis baca dan mencetak TRUEatau dengan FALSEtepat:

while IFS= read -r -u3 line1; IFS= read -r -u4 line2; do
    [[ $line1 == $line2 ]] && echo TRUE || echo FALSE
done 3<file1 4<file2

Dua panggilan untuk readmembaca dari file deskriptor 3 dan 4 masing-masing. File diarahkan ke ini dengan dua pengalihan input ke dalam loop.

glenn jackman
sumber
0
Tried with awk command and it worked fine


awk 'NR==FNR{a[$1];next}{if ($1 in a){print "TRUE"} else{print "False"}}' file1 file2

keluaran

TRUE
TRUE
False
False
Praveen Kumar BS
sumber