Jeg vil utføre det noen dataanalyseprogramvare kaller anti-join: fjern disse linjene fra en liste samsvarende linjer i en annen liste. Her er noen leketøydata og forventet utdata:
$ echo -e "a\nb\nc\nd" > list1 $ echo -e "c\nd\ne\nf" > list2 $ antijoincommand list1 list2 a b
Kommentarer
- Relatert unix.stackexchange.com/q/11343/117549
- Svarer dette på spørsmålet ditt? Er det et verktøy for å få linjene i en fil som ikke er i en annen?
- @Muru, ja, det innlegget gir løsningene presentert i Terdon ' s svar. Da jeg imidlertid lette etter " bash anti-join " (terminologien jeg forbinder med denne typen prosesser), gjorde jeg ikke ' t finner noe nyttig. Min OP (som andre har redigert) uttalte at mitt eksplisitte formål med å stille dette spørsmålet var å knytte begrepet " anti-join " til løsningene, slik at søking i dette begrepet gir disse løsningene. Takk.
Svar
Jeg vil ikke bruke join
for dette fordi join
krever at input blir sortert, noe som er en unødvendig komplikasjon for en så enkel jobb. Du kan i stedet bruke grep
:
$ grep -vxFf list2 list1 a b
Eller awk
:
$ awk "NR==FNR{++a[$0]} !a[$0]" list2 list1 a b
Hvis filene allerede er sortert, ville et alternativ til join -v 1
være comm -23
$ comm -23 list1 list2 a b
Kommentarer
- Å unngå
sort
medgrep
er flott for leketøydataene jeg har oppgitt. Takk! I den virkelige verden har filen1 ofte flere kolonner med data, hvorav den ene brukes til sammenføyningen. En modifisert versjon avawk
koden vil adressere denne brukssaken. - @Josh ja, bare endre
$0
med$N
derN
er feltnummeret du blir med på. - Dette fungerer selv om kolonnetallene i file1 og file2 er forskjellige: som awk ' NR == FNR {++ a [$ 2]}! a [$ 5] ' list2 liste1; ganske vanlig for at tagfilen skal være et annet format enn hoveddataene.
Svar
En måte å gjør dette med join
verktøyet er:
$ join -v 1 list1 list2 a b