Anti-join vagy inverse join végrehajtása a bash

Azt akarom végrehajtani, amit egyes adatelemző szoftverek anti-join-nak neveznek: távolítsa el ezeket a sorokat egy listából egyező sorok egy másik listában. Íme néhány játékadat és a várható kimenet:

$ echo -e "a\nb\nc\nd" > list1 $ echo -e "c\nd\ne\nf" > list2 $ antijoincommand list1 list2 a b 

Megjegyzések

  • Kapcsolódó unix.stackexchange.com/q/11343/117549
  • Ez megválaszolja a kérdését? Van-e eszköz az egyik fájl sorainak megszerzéséhez, amelyek nem a másikban vannak?
  • @Muru, igen, ez a bejegyzés biztosítja a megoldásokat Terdon ' válaszában jelenik meg. Amikor azonban a " bash anti-join " (az ilyen folyamathoz társított terminológiát) kifejezésre kerestem, nem tettem ' nem talál semmi hasznosat. Az operatív programomban (amelyet mások szerkesztettek) kijelentettem, hogy kifejezetten az volt a célom, hogy ezt a kérdést feltegyem a " anti-join " kifejezés társítására a megoldásokat, így ennek a kifejezésnek a keresése eredményezi ezeket a megoldásokat. Köszönöm.

Válasz

Nem használnám a join Erre azért van szükség, mert a join megköveteli az input rendezését, ami felesleges bonyolultság egy ilyen egyszerű munkához. Ehelyett használhatja a grep:

$ grep -vxFf list2 list1 a b 

Vagy awk:

$ awk "NR==FNR{++a[$0]} !a[$0]" list2 list1 a b 

Ha a fájlok már rendezve vannak, akkor a join -v 1 alternatívája a comm -23

$ comm -23 list1 list2 a b 

Megjegyzések

  • A sort elkerülése nagyszerű a grep használatával az általam megadott játékadatokért. Köszönet! A való világban a fájlom1 gyakran több oszlopnyi adattal rendelkezik, amelyek közül az egyiket a csatlakozáshoz használják. A awk módosított változata kód kezelné ezt a felhasználási esetet.
  • @Josh igen, csak változtassa meg a $0 -et $N hova A N az a mezőszám, amelyhez csatlakozik.
  • Ez akkor is működik, ha az 1. és a 2. fájl oszlopszáma eltér: például awk ' NR == FNR {++ a [$ 2]}! a [$ 5] ' list2 lista1; nagyon szokásos, hogy a címkefájl formátuma eltér a fő adatoktól.

Válasz

Az egyik módja annak, hogy tegye ezt a join segédprogrammal:

$ join -v 1 list1 list2 a b 

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük