Unix'te iki farklı dosyayı satır satır nasıl karşılaştırırım?


13

file1:

123
234
345
456

file2:

123
234
343
758

Beklenen çıktı: Dosya3:

TRUE
TRUE
FALSE
FALSE

kod iki dosyayı karşılaştırmalı ve eşleşirse 'TRUE' yazmalıdır, aksi takdirde yeni dosyada 'FALSE' yazmalıdır. Herkes bunun için çözüm sağlayabilir mi?


10
İki dosya aynı uzunlukta değilse ne olur? Bu sorunun çözümünün hangi kısmında sorun yaşıyorsunuz?
Kusalananda

9
Bir göz atmak isteyebilirsiniz diff.
Panki

2
Bu durumlarda diğer yararlı komuttur comm. Her iki dosyanın da ortak olduğu veya bir veya diğerine özgü satırları listelemeyi kolaylaştırır.
Giacomo Alzetta

1
@GiacomoAlzetta Önemli olan commsıralı girdi gerektirmesidir. Sorudaki örnek girdiyi sıralamış olmasının yanı sıra , soru bunun kullanılmakta olan gerçek veri olduğunu asla iddia etmez ve asla verilerin sıralaması hakkında hiçbir şey söylemez.
Kusalananda

2
αғsнιη'in nlhilesi, commdosyalara sıralılık koymak için kullanışlıdır .
glenn jackman

Yanıtlar:


56

diffKomutu aşağıdaki gibi, işlem ikamelerinibash destekleyen başka bir kabukta kullanın veya burada gösterildiği gibi taklit edebilirsiniz :<(...)

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

Çıktı:

TRUE
TRUE
FALSE
FALSE

--new-line-format='FALSE'$'\n, FALSEsatırlar farklıysa yazdırın ve --old-line-format=''farklı komut için eski dosya olarak bilinen dosya1 için satır farklıysa çıktıyı devre dışı bırakırız (Bunları da değiştirebiliriz, yani bunlardan biri FALSEdiğerini yazdırmalıdır , devre dışı bırakılmalıdır.)

--unchanged-line-format='TRUE'$'\n', TRUEsatırlar aynıysa yazdır . $'\n'C tarzı kaçan sözdizimi, her satır çıkış sonra yeni bir satır baskı için kullanılmaktadır.


24

Dosyaların sekme karakteri içermediği varsayılarak:

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

Bu, pasteher iki sütundaki iki dosyanın içeriği ile iki sekmeyle ayrılmış sütun oluşturmak için kullanılır . awkKomut, her satırda iki sütun karşılaştırır ve basar TRUEsütunlar aynı ve aksi takdirde baskılar ise FALSE.


10

Her iki dosyanın da aynı sayıda satıra sahip olduğu varsayılarak:

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

Karşılaştırılacak dizeler sayılar ve tersi ise, sayısal bir karşılaştırma yapar. Örneğin, 100ve 1.0e2aynı olarak düşünülebilir. f2"" == $0Her durumda sözcüksel karşılaştırmayı zorlamak için değiştirin .

Uygulamaya bağlı olarak awk, sözcüksel karşılaştırma memcmp()(bayt-bayt karşılaştırması) veya sanki strcoll()(iki dizenin yerel ayarın harmanlama düzeninde aynı sıralanıp sıralanmadığı) kullanılarak yapılacaktır. Bu, siparişin bazı karakterler için düzgün tanımlanmadığı bazı örneklerde fark yaratabilir, örneğin örneğinizdeki gibi tüm ondalık basamak girişlerinde değil.


7

Python 3

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

Çıktı:

True
True
False
False

Gerekirse TRUEve FALSEbüyük harfle yazdırılıyorsa, yazdırma satırını aşağıdakilerden biriyle değiştirin:

print(str(line1 == line2).upper())
print('TRUE' if line1 == line2 else 'FALSE')

2
Python 2'de bir import itertoolsilk yapın ve itertools.izipyerine kullanın zip. Aksi takdirde, her iki dosyayı da belleğe okuyacaktır, muhtemelen çok fazla bellek kullanır.
pts

4

İçinde bash, bir whiledöngüdeki her dosyadan okuma , okuma satırlarını karşılaştırma ve yazdırma TRUEveya FALSEuygun şekilde:

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

İki readdosya sırasıyla 3 ve 4. dosya tanımlayıcısından okuma çağrısı yapar . Dosyalar, döngüye iki giriş yönlendirmesi ile bunlara yönlendirilir.


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

çıktı

TRUE
TRUE
False
False
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.