Voglio eseguire quello che alcuni software di analisi dei dati chiamano anti-join: rimuovere da un elenco quelle righe righe corrispondenti in un altro elenco. Di seguito sono riportati alcuni dati sui giocattoli e loutput previsto:
$ echo -e "a\nb\nc\nd" > list1 $ echo -e "c\nd\ne\nf" > list2 $ antijoincommand list1 list2 a b
Commenti
- Correlazione unix.stackexchange.com/q/11343/117549
- Questo risponde alla tua domanda? Esiste uno strumento per ottenere le righe in un file che non sono in un altro?
- @Muru, sì, quel post fornisce le soluzioni presentato nella risposta di Terdon '. Tuttavia, quando stavo cercando " bash anti-join " (la terminologia che associo a questo tipo di processo), non lho fatto ' non trovi niente di utile. Il mio OP (che altri hanno modificato) ha affermato che il mio scopo esplicito nel porre questa domanda era associare il termine " anti-join " con le soluzioni, in modo che la ricerca di questo termine produca queste soluzioni. Grazie.
Risposta
Non userei join
per questo perché join
richiede lordinamento dellinput, il che è una complicazione non necessaria per un lavoro così semplice. Puoi invece utilizzare grep
:
$ grep -vxFf list2 list1 a b
Oppure awk
:
$ awk "NR==FNR{++a[$0]} !a[$0]" list2 list1 a b
Se i file sono già ordinati, unalternativa a join -v 1
sarebbe comm -23
$ comm -23 list1 list2 a b
Commenti
- Evitare
sort
congrep
è fantastico per i dati del giocattolo che ho fornito. Grazie! Nel mondo reale, il mio file1 ha spesso più colonne di dati, una delle quali viene utilizzata per il join. Una versione modificata del tuoawk
il codice risolverà questo caso duso. - @Josh sì, basta cambiare
$0
con$N
doveN
è il numero di campo a cui ti stai unendo. - Funziona anche se i numeri di colonna in file1 e file2 sono diversi: come awk ' NR == FNR {++ a [$ 2]}! a [$ 5] ' list2 list1; abbastanza normale che il file tag abbia un formato diverso dai dati principali.
Risposta
Un modo per farlo con lutilità join
è:
$ join -v 1 list1 list2 a b