Jeg vil udføre, hvad nogle dataanalysesoftware kalder en anti-join: fjern disse linjer fra en liste matchende linjer i en anden liste. Her er nogle legetøjsdata og den forventede output:
$ echo -e "a\nb\nc\nd" > list1 $ echo -e "c\nd\ne\nf" > list2 $ antijoincommand list1 list2 a b
Kommentarer
- Forhold unix.stackexchange.com/q/11343/117549
- Besvarer dette dit spørgsmål? Er der et værktøj til at få linjerne i en fil, der ikke er i en anden?
- @Muru, ja, det indlæg giver løsningerne præsenteret i Terdon ' s svar. Da jeg søgte efter " bash anti-join " (den terminologi, jeg forbinder med denne form for proces), gjorde jeg ikke ' t finde noget nyttigt. Min OP (som andre har redigeret) sagde, at mit eksplicitte formål med at stille dette spørgsmål var at knytte udtrykket " anti-join " til løsningerne, så at søge i dette udtryk giver disse løsninger. Tak.
Svar
Jeg vil ikke bruge join
til dette fordi join
kræver, at input sorteres, hvilket er en unødvendig komplikation for et så simpelt job. Du kan i stedet bruge grep
:
$ grep -vxFf list2 list1 a b
Eller awk
:
$ awk "NR==FNR{++a[$0]} !a[$0]" list2 list1 a b
Hvis filerne allerede er sorteret, ville et alternativ til join -v 1
være comm -23
$ comm -23 list1 list2 a b
Kommentarer
- Undgå
sort
medgrep
er fantastisk til de legetøjsdata, jeg leverede. Tak! I den virkelige verden har min fil1 ofte flere kolonner med data, hvoraf den ene bruges til sammenføjningen. En ændret version af dinawk
kode vil adressere denne brugssag. - @Josh ja, skift bare
$0
med$N
N
er feltnummeret, du deltager i. - Dette fungerer, selvom kolonnetalene i fil1 og fil2 er forskellige: som awk ' NR == FNR {++ a [$ 2]}! a [$ 5] ' list2 liste1; ganske almindeligt, at tagfilen skal være et andet format end hoveddataene.
Svar
En måde at gør dette med join
hjælpeprogrammet er:
$ join -v 1 list1 list2 a b