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
sort
cugrep
este 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ă aawk
codul ar aborda acest caz de utilizare. - @Josh da, trebuie doar să schimbi
$0
cu$N
undeN
este 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