Vreau să realizez ceea ce unele software-uri de analiză a datelor numesc anti-join: eliminați dintr-o listă acele linii potrivirea liniilor într-o altă listă. Iată câteva date despre jucării și rezultatul așteptat:
$ echo -e "a\nb\nc\nd" > list1 $ echo -e "c\nd\ne\nf" > list2 $ antijoincommand list1 list2 a b
Comentarii
- Relatarea unix.stackexchange.com/q/11343/117549
- Vă răspunde această întrebare? Există un instrument pentru a obține liniile dintr-un fișier care nu se află într-un altul?
- @Muru, da, postarea respectivă oferă soluțiile prezentat în răspunsul Terdon '. Cu toate acestea, când căutam " bash anti-join " (terminologia pe care o asociez cu acest tip de proces), nu am ' nu găsești nimic util. OP-ul meu (pe care alții l-au editat) a declarat că scopul meu explicit în a pune această întrebare a fost de a asocia termenul " anti-join " soluțiile, astfel încât căutarea acestui termen produce aceste soluții. Mulțumesc.
Răspuns
Nu aș folosi join pentru aceasta, deoarece join necesită sortarea intrărilor, ceea ce reprezintă o complicație inutilă pentru o lucrare atât de simplă. În schimb, puteți utiliza grep:
$ grep -vxFf list2 list1 a b
Sau awk:
$ awk "NR==FNR{++a[$0]} !a[$0]" list2 list1 a b
Dacă fișierele sunt deja sortate, o alternativă la join -v 1 ar fi comm -23
$ comm -23 list1 list2 a b
Comentarii
- Evitarea
sortcugrepeste grozavă pentru datele despre jucării pe care le-am furnizat. Mulțumesc! În lumea reală, fișierul meu1 are adesea mai multe coloane de date, dintre care una este utilizată pentru îmbinare. O versiune modificată aawkcodul ar aborda acest caz de utilizare. - @Josh da, trebuie doar să schimbi
$0cu$NundeNeste numărul câmpului la care vă alăturați. - Acest lucru funcționează chiar dacă numerele coloanelor din fișierul1 și fișierul2 sunt diferite: cum ar fi awk ' NR == FNR {++ a [$ 2]}! a [$ 5] ' list2 list1; destul de obișnuit ca fișierul de etichete să aibă un format diferit față de datele principale.
Răspuns
O modalitate de a faceți acest lucru cu utilitarul join este:
$ join -v 1 list1 list2 a b