Você mencionou o comando join , mas, nesse caso, não é fácil usá-lo. Pelo menos não por si só.
Vamos tentar juntar os dois arquivos. Para fazer isso, os arquivos precisam ser classificados primeiro no campo de junção. Vamos usar o segundo campo do primeiro arquivo e o primeiro campo (que é o padrão para join ) do segundo arquivo:
$ sort -k2 -o main.txt main.txt
$ sort -k1 -o changes.txt changes.txt
Então fazemos a junção:
$ join -1 2 main.txt changes.txt
genre_A word_1 root_A
genre_A word_2 root_A
genre_A word_5 root_A
genre_C word_4 root_C
Estamos perdendo uma linha. Tente novamente e diga join para também as linhas de saída de main.txt que seriam deixadas de fora (porque elas não correspondem a nada em changes.txt ):
$ join -1 2 -a 1 main.txt changes.txt
genre_A word_1 root_A
genre_A word_2 root_A
genre_A word_5 root_A
word_3 genre_B
genre_C word_4 root_C
Observe que não podemos pedir ao join para enviar apenas algumas das colunas de um dos arquivos porque a segunda coluna na saída desejada contém uma mistura de dados dos dois arquivos.
No entanto, com a saída acima, podemos extrair as duas últimas colunas usando um simples script awk (desejo que cut possa ter especificações de campo negativas para obter colunas da direita!):
$ join -1 2 -a 1 main.txt changes.txt | awk '{ print $(NF-1), $NF }'
word_1 root_A
word_2 root_A
word_5 root_A
word_3 genre_B
word_4 root_C
Canalize isso para sort para classificação:
$ join -1 2 -a 1 main.txt changes.txt | awk '{ print $(NF-1), $NF }' | sort
word_1 root_A
word_2 root_A
word_3 genre_B
word_4 root_C
word_5 root_A