Liste der Elemente aus einer anderen Datei in Bash entfernen

567
dronus

Was wäre die effizienteste Methode (keine wiederholte Befehlsausführung), um in einer Datei aufgelistete Elemente aus einer anderen Datei zu entfernen (ungeordnet)?

Man kann leicht die Liste der nicht übereinstimmenden Elemente in der zweiten Datei abrufen

cat first_file.txt second_file.txt | sort | uniq -u 

aber das würde auch alle unübertroffenen Elemente aus der ersten Datei enthalten ... was nun?

0

1 Antwort auf die Frage

1
glenn jackman

Dieses awkProgramm durchläuft jede Datei einmalig:

awk ' NR == FNR  !($0 in f1) ' file1 file2 

comm ist nützlich für diesen Job. Die Eingabedateien müssen jedoch sortiert werden:

# output lines unique to file2 comm -13 <(sort file1) <(sort file2) 
Ich habe keine Ahnung, wie `! ($ 0 in f1)` intern funktioniert, ich meine __in__ in _awk_. Wenn alle Arrays einfach gescannt werden, sollten wir dort O (n!) Haben. : - | _sort_ scheint es [hoch optimiert] (http://vkundeti.blogspot.ru/2008/03/tech-algorithmic-details-of-unix-sort.html) zu sein ... Haben Sie einen Hinweis? Hastur vor 8 Jahren 0
Der In-Operator prüft, ob der linke Operand ein Index des (assoziativen oder indizierten) Arrays ist. Es sollte eine O (1) -Operation sein. Für gawk, hier dokumentiert: http://www.gnu.org/software/gawk/manual/html_node/Reference-to-Elements.html#Reference-to-Elements glenn jackman vor 8 Jahren 0
Danke für den Hinweis. __`in`__ sollte das gesamte Array 'f1' nicht nur ein Element scannen, von hier aus O (n ^ 2) [BTW Errata im vorherigen Kommentar O (n ^ 2) und nicht O (n!)]. Ich habe einen Test mit 10 ^ 4 bis 10 ^ 6 zufälligen Strings von 32 Bytes durchgeführt, und die Lösung "awk" skaliert linear: Es muss eine Reihenfolge sein. (Die "comm" -Lösung variiert mehr 2x bei 10 ^ 4, ~ 1x bei 10 ^ 5 und 2x 10 ^ 6, aber ich nehme an, es hängt vom verfügbaren Speicher ab). Hastur vor 8 Jahren 0
Cool, ich wusste nichts über "comm". dronus vor 8 Jahren 0