Com awk , algo assim:
awk -F\; 'NR == FNR {A[$0]=1; next}; A[$2] == 1;' emails.txt john*.txt
NR == FNR testa se o número do registro (line) contado em todos os arquivos é o mesmo que o número do registro no arquivo atual, o que é uma maneira divertida de testar se esse é o primeiro arquivo. Se estiver, tomamos a linha completa como lida ( $0 ) e a usamos como chave para uma matriz associativa chamada A , definindo o valor como um e pulando para a linha next da entrada. Se não foi o primeiro arquivo (o salto não foi tirado), pegue o segundo campo ( $2 ) na linha, separado por ponto e vírgula (definido por -F ) e veja se o valor correspondente na matriz A é um deles. Se for, a ação padrão é imprimir a linha inteira. Você pode adicionar, digamos, {print $1} para imprimir apenas o primeiro campo.
Com grep você poderia fazer
grep -F -f emails.txt john*.txt
( -F para padrões de sequência fixa, -f para ler padrões de um arquivo.)
Mas isso também imprimirá correspondências parciais e também corresponderá a outros campos do arquivo, mas isso pode não ser um problema com nomes, números de telefone e endereços de e-mail.
Embora isso possa ser contornado adicionando ponto e vírgula ao início e ao final de cada linha usada como padrão. Isso deve funcionar se a substituição do processo for suportada:
grep -F -f <(sed -e 's/^/;/' -e 's/$/;/' emails.txt) john*.txt