Como comparar todos os arquivos no diretório com outro arquivo e imprimir a saída de linhas comuns

2

Primeiro eu tenho um diretório / consistindo de 100 arquivos .txt

john_1.txt , john_2.txt , john_3.txt , john_4.txt etc, que consiste em ex. %código% e depois eu tenho um outro arquivo id;email;name;phone que consiste em endereços de e-mail listados linha por linha.

Como faço para comparar todos os arquivos com este arquivo de e-mails e imprimo as linhas comuns.

emails.txt ou grep ?

    
por Axel Tobieson 31.07.2016 / 21:18

1 resposta

2

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 
    
por 31.07.2016 / 22:34