Chci provést to, co některý software pro analýzu dat nazývá anti-join: odstranit tyto řádky z jednoho seznamu odpovídající řádky v jiném seznamu. Tady je několik údajů o hračkách a očekávaný výstup:
$ echo -e "a\nb\nc\nd" > list1 $ echo -e "c\nd\ne\nf" > list2 $ antijoincommand list1 list2 a b
Komentáře
- Související unix.stackexchange.com/q/11343/117549
- Odpovídá to na vaši otázku? Existuje nástroj pro získání řádků v jednom souboru, které nejsou v jiném?
- @Muru, ano, tento příspěvek poskytuje řešení uvedené v odpovědi Terdon '. Když jsem však hledal " bash anti-join " (terminologie, kterou s tímto druhem procesu spojuji), neudělal jsem ' nenajde nic užitečného. Můj OP (který ostatní upravili) uvedl, že mým výslovným cílem při kladení této otázky bylo spojit termín " anti-join " s řešení, takže hledání tohoto výrazu tato řešení přinese. Děkuji.
Odpověď
Nepoužívám join
z tohoto důvodu, protože join
vyžaduje třídění vstupu, což je pro tak jednoduchou práci zbytečná komplikace. Místo toho můžete použít grep
:
$ grep -vxFf list2 list1 a b
Nebo awk
:
$ awk "NR==FNR{++a[$0]} !a[$0]" list2 list1 a b
Pokud jsou soubory již seřazeny, alternativou k join -v 1
by byla comm -23
$ comm -23 list1 list2 a b
Komentáře
- Vyhýbání se
sort
sgrep
je skvělé za údaje o hračce, které jsem poskytl. Díky! Ve skutečném světě má můj soubor1 často více sloupců dat, z nichž jeden se používá pro spojení. Upravená verze vašehoawk
kód by řešil tento případ použití. - @Josh ano, stačí změnit
$0
na$N
kdeN
je číslo pole, ke kterému se připojujete. - Funguje to i v případě, že se čísla sloupců v souborech1 a souborech 2 liší: jako awk ' NR == FNR {++ a [$ 2]}! a [$ 5] ' list2 list1; celkem obvyklé, že soubor tagu má jiný formát než hlavní data.
Odpověď
Jeden způsob, jak proveďte to pomocí join
nástroje:
$ join -v 1 list1 list2 a b