Twee bestanden vergelijken in linux-terminal

Er zijn twee bestanden met de naam “a.txt”en “b.txt”die beide een lijst met woorden hebben. Nu wil ik controleren welke woorden extra zijn in “a.txt”en niet in “b.txt”.

Ik heb een efficiënt algoritme nodig omdat ik twee woordenboeken moet vergelijken.


Antwoord 1, autoriteit 100%

als je vim hebt geïnstalleerd, probeer dan dit:

vimdiff file1 file2

of

vim -d file1 file2

je zult het fantastisch vinden.


Antwoord 2, autoriteit 21%

Sorteer ze en gebruik comm:

comm -23 <(sort a.txt) <(sort b.txt)

commvergelijkt (gesorteerde) invoerbestanden en geeft standaard drie kolommen weer: regels die uniek zijn voor a, regels die uniek zijn voor b en regels die in beide voorkomen. Door -1, -2en/of -3op te geven, kunt u de bijbehorende uitvoer onderdrukken. Daarom vermeldt comm -23 a balleen de items die uniek zijn voor a. Ik gebruik de syntaxis <(...)om de bestanden direct te sorteren, als ze al zijn gesorteerd, heb je dit niet nodig.


Antwoord 3, autoriteit 9%

Als je de diff-uitvoerstijl van git diffverkiest, kun je deze gebruiken met de vlag --no-indexom bestanden te vergelijken die niet in een git-repository staan:

git diff --no-index a.txt b.txt

Met behulp van een aantal bestanden met elk ongeveer 200k bestandsnaamreeksen, heb ik deze benadering vergeleken (met het ingebouwde time-commando) versus enkele van de andere antwoorden hier:

git diff --no-index a.txt b.txt
# ~1.2s
comm -23 <(sort a.txt) <(sort b.txt)
# ~0.2s
diff a.txt b.txt
# ~2.6s
sdiff a.txt b.txt
# ~2.7s
vimdiff a.txt b.txt
# ~3.2s

commlijkt verreweg de snelste te zijn, terwijl git diff --no-indexde snelste benadering lijkt te zijn voor uitvoer in diff-stijl.


Update 25-03-2018U kunt de vlag --no-indexzelfs weglaten, tenzij u zich in een git-repository bevindt en niet-getrackte bestanden in die repository wilt vergelijken . Van de man-pagina’s:

Dit formulier is bedoeld om de gegeven twee paden op het bestandssysteem te vergelijken. Je kunt de –no-index optie weglaten als het commando wordt uitgevoerd in een werkboom die wordt beheerd door Git en ten minste één van de paden buiten de werkboom wijst, of als het commando buiten een werkboom wordt uitgevoerd die wordt beheerd door Git.


Antwoord 4, autoriteit 9%

Probeer sdiff(man sdiff)

sdiff -s file1 file2

Antwoord 5, autoriteit 8%

Je kunt de difftool in linux gebruiken om twee bestanden te vergelijken. U kunt de opties –changed-group-formaten –unchanged-group-formatgebruiken om de vereiste gegevens te filteren.

De volgende drie opties kunnen worden gebruikt om de relevante groep voor elke optie te selecteren:

  • ‘%<‘ haal regels uit FILE1

  • ‘%>’ haal regels uit FILE2

  • ” (lege string) voor het verwijderen van regels uit beide bestanden.

Bijvoorbeeld: diff –changed-group-format=”%<” –unchanged-group-format=”” file1.txt file2.txt

[root@vmoracle11 tmp]# cat file1.txt 
test one
test two
test three
test four
test eight
[root@vmoracle11 tmp]# cat file2.txt 
test one
test three
test nine
[root@vmoracle11 tmp]# diff --changed-group-format='%<' --unchanged-group-format='' file1.txt file2.txt 
test two
test four
test eight

Antwoord 6, Autoriteit 2%

U kunt ook gebruik maken van: colordiff :. Geeft de uitvoer van diff met kleuren

Over vimdiff : Hiermee kunt u bestanden te vergelijken via SSH, bijvoorbeeld:

vimdiff /var/log/secure scp://192.168.1.25/var/log/secure

Gewonnen uit: http: //www.sysadmit .com / 2016/05 / linux-diferencias-entre-dos-archivos.html


Antwoord 7, Autoriteit 2%

Ook, vergeet niet over mcdiff – Interne diff viewer of GNU Midnight Commander .

Bijvoorbeeld:

mcdiff file1 file2

Geniet!


Antwoord 8

Gebruik comm -13(vereist gesorteerde bestanden)

$ cat file1
one
two
three
$ cat file2
one
two
three
four
$ comm -13 <(sort file1) <(sort file2)
four

Antwoord 9

Hier is mijn oplossing voor dit:

mkdir temp
mkdir results
cp /usr/share/dict/american-english ~/temp/american-english-dictionary
cp /usr/share/dict/british-english ~/temp/british-english-dictionary
cat ~/temp/american-english-dictionary | wc -l > ~/results/count-american-english-dictionary
cat ~/temp/british-english-dictionary | wc -l > ~/results/count-british-english-dictionary
grep -Fxf ~/temp/american-english-dictionary ~/temp/british-english-dictionary > ~/results/common-english
grep -Fxvf ~/results/common-english ~/temp/american-english-dictionary > ~/results/unique-american-english
grep -Fxvf ~/results/common-english ~/temp/british-english-dictionary > ~/results/unique-british-english

Antwoord 10

U kunt ook het volgende gebruiken:

sdiff file1 file2

Om verschillen naast elkaar weer te geven in uw terminal!


Antwoord 11

Awk ervoor gebruiken. Testbestanden:

$ cat a.txt
one
two
three
four
four
$ cat b.txt
three
two
one

De awk:

$ awk '
NR==FNR {                    # process b.txt  or the first file
    seen[$0]                 # hash words to hash seen
    next                     # next word in b.txt
}                            # process a.txt  or all files after the first
!($0 in seen)' b.txt a.txt   # if word is not hashed to seen, output it

Duplicaten worden uitgevoerd:

four
four

Om duplicaten te voorkomen, voegt u elk nieuw gevonden woord in a.txt toe aan de seen-hash:

$ awk '
NR==FNR {
    seen[$0]
    next
}
!($0 in seen) {              # if word is not hashed to seen
    seen[$0]                 # hash unseen a.txt words to seen to avoid duplicates 
    print                    # and output it
}' b.txt a.txt

Uitvoer:

four

Als de woordenlijsten door komma’s worden gescheiden, zoals:

$ cat a.txt
four,four,three,three,two,one
five,six
$ cat b.txt
one,two,three

je moet een paar extra ronden rijden (forloops):

awk -F, '                    # comma-separated input
NR==FNR {
    for(i=1;i<=NF;i++)       # loop all comma-separated fields
        seen[$i]
    next
}
{
    for(i=1;i<=NF;i++)
        if(!($i in seen)) {
             seen[$i]        # this time we buffer output (below):
             buffer=buffer (buffer==""?"":",") $i
        }
    if(buffer!="") {         # output unempty buffers after each record in a.txt
        print buffer
        buffer=""
    }
}' b.txt a.txt

Uitgang deze keer:

four
five,six

Other episodes