Come eseguire lanti-join o linverso join in bash

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 con grep è 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 tuo awk il codice risolverà questo caso duso.
  • @Josh sì, basta cambiare $0 con $N dove N è 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 

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *