Wenn Ihr Ziel darin besteht, gemeinsame oder ungewöhnliche Linien zu finden, comm
wäre dies mein Befehl hier.
Es vergleicht zwei Dateien und zeigt in drei Spalten Zeilen an, die für Datei 1 eindeutig sind, Zeilen, die für Datei 2 eindeutig sind, und Zeilen, die in beiden Dateien angezeigt werden. Sie können es-Flags übergeben, um auch diese Ausgabe zu unterdrücken. ZB comm -1 file1 file2
wird die erste Spalte unterdrückt, die Dinge, die nur für Datei1 gelten. comm -12 file1 file2
würde nur Dinge in beiden Dateien zeigen.
Es gibt eine große Einschränkung: Die Eingabe muss sortiert werden. Wir können das umgehen.
Dies zeigt Ihnen alles in abc, was nicht in mno ist:
comm -23 <(sort abc.txt) <(sort mno.txt)
Und Sie können das einpfeifen, wc -l
um eine Zählung zu erhalten.
Der Grund, warum ich mich dafür entscheide, comm
ist, dass der Vergleich nebeneinander nach dem Sortieren der Dateien rechnerisch sehr einfach ist. Wenn Sie mit Millionen davon zu tun haben, wird das einen Unterschied machen.
Dies kann mit einigen Scheindateien demonstriert werden. Ich habe einen ziemlich schnellen Computer, um den Unterschied zwischen den Ansätzen zu zeigen, brauche ich ein ziemlich großes Probenset. Ich habe 10 Millionen 10-Zeichen-Zeichenfolgen pro Datei verwendet.
$ cat /dev/urandom | tr -dc '0-9' | fold -w 10 | head -10000000 > abc.txt
$ cat /dev/urandom | tr -dc '0-9' | fold -w 10 | head -10000000 > mno.txt
$ time comm -23 <(sort abc.txt) <(sort mno.txt) | wc -l
... 0m10.653s
$ time grep -Fcxv -f abc.txt mno.txt
... 0m23.920s
$ time grep -Fcwv -f abc.txt mno.txt
... 0m40.313s
$ time awk 'NR==FNR{a[$0]++};NR!=FNR && a[$0]' abc.txt mno.txt | wc -l
... 0m12.161s
Das Sortieren dauert bei mir die meiste Zeit. Wenn wir so tun, als wäre abc.txt statisch, können wir es vorsortieren, was zukünftige Vergleiche viel schneller macht:
$ sort abc.txt abc-sorted.txt
$ time comm -23 abc-sorted.txt <(sort mno.txt) | wc -l
... 0m7.426s
Sie könnten sich diese ansehen und einige Sekunden für irrelevant halten, aber ich muss hervorheben, dass diese auf einem High-End-Computer ausgeführt werden. Wenn Sie dies auf einem (z. B.) Raspberry Pi 3 tun möchten, werden Sie viel langsamere Turnarounds sehen und der Unterschied wird bis zu einem Punkt zunehmen, der tatsächlich wichtig ist.
grep -cxvFf abc.txt mno.txt
?fgrep
,egrep
ist wechselt angeblich veraltet (fürgrep -F
,grep -E
- obwohl ich jemand bin nicht sicher , glaubt sie immer weggeht-x
bei der Verwendung zu verwenden-F
?abcdef
sollte das als Übereinstimmung oder Nichtübereinstimmung geltenabcd
?Wir könnten awk verwenden, um die Arbeit zu erledigen, indem wir zwei Dateien übergeben, zuerst die Musterdatei, dann die Datei, die wir überprüfen möchten. Wenn wir die erste Datei lesen, wissen wir das
NR==FNR
und können zu diesem Zeitpunkt Zeilen in ein Array einlesen. WennNR!=FNR
wir prüfen, ob das Array für eine solche Zeile festgelegt ist.Umgekehrt können wir das Muster negieren, um die Zeilen zu drucken, die nicht vorhanden sind
abc.txt
Und wenn wir die Anzahl derer ausdrucken möchten, die wir beschäftigen können,
sort
undwc
:quelle
abc.txt
-mno.txt
das ist{xyz, pqrs}
.Wenn eine der Wortlisten unsortiert ist, ist es schneller, eine effiziente Satzdatenstruktur zu verwenden, um sich an die gebräuchlichen Wörter zu erinnern.
Python
Verwendungszweck:
Python (effizienter)
Wenn Sie ein wenig Speicher für Zwischenspeicher und Laufzeit sparen möchten, können Sie dieses etwas schwieriger zu verstehende Programm verwenden:
Performance
Gegeben
abc.txt
undmno.txt
mit 1 Million unsortierten Zeilen mit jeweils 10 zufälligen ASCII-Ziffern (siehe Olis Antwort für die Einrichtung):vs.
Gesamt: 23 Sekunden
quelle