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
sortsgrepje 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šehoawkkód by řešil tento případ použití. - @Josh ano, stačí změnit
$0na$NkdeNje čí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