se a saída puder ser classificada:
join <(sort file1.txt) <(sort file2.txt)
Procurando comparar a primeira coluna de dois arquivos de entrada que possuem um formato idêntico. O formato é semelhante ao seguinte:
FILE1:
0000abc5abc3 GR096
0000def5ae87 GR001
0000cab5aea3 GR001
0000bac5aeeb GR001
0000fed5af13 GR001
0000efd5b16f GR001
0000cba5b187 GR001
0000bca5b2a3 GR001
FILE2:
0000abc5abc3 GR097
0000def5ae87 GR001
0000cab5aea3 GR001
0000bac5aeeb GR001
0000fed5af13 GR123
0000cba5b187 GR169
A coluna 1 contém endereços MAC em FILE1 e FILE2. Eu quero o valor da coluna 1 no FILE1 para verificar contra coluna 1 no FILE2 e se houver uma correspondência para saída o valor da coluna 1 e coluna 2 de FILE1 e o valor da coluna 2 no FILE2 como uma terceira coluna dessa maneira.
DESIRED OUTPUT:
0000abc5abc3 GR096 GR097
0000def5ae87 GR001 GR001
0000cba5b187 GR001 GR169
Cada arquivo contém vários milhões de entradas. Executar a entrada no bash é eternamente lento e ineficiente usando loops while enquanto faz um loop em cada entrada:
while read -r mac1 code1; do
while read -r mac2 code2 ; do
if [ "$mac1" == "$mac2" ]; then
printf "%s %s %s\n" "$mac1" "$code1" "$code2"
fi
done < "$FILE1"
done < "$FILE2" > OUTPUTFILE
O awk é significativamente mais rápido para mim usando arrays, mas não consigo imprimir a segunda coluna do FILE2 na terceira coluna da saída usando uma sintaxe como a seguinte. Esta sintaxe apenas imprime a coluna 2 uma segunda vez:
awk 'NR==FNR { n[$1] = $1; n[$2] = $2; next } ($1 in n) { print n[$1],n[$2],$2 }'
Minha preferência é AWK, mas se ele pode ser executado no bash com a mesma rapidez, também estou bem com isso.
Resumo: Se o valor na Coluna 1 no arquivo1 for encontrado no arquivo2, imprima o valor da coluna 1, coluna 2 (Arquivo1) e coluna2 (Arquivo2).
Apenas para corrigir o seu awk:
awk 'NR==FNR { n[$1]=$0;next } ($1 in n) { print n[$1],$2 }' file1 file2
#Output:
0000abc5abc3 GR096 GR097
0000def5ae87 GR001 GR001
0000cab5aea3 GR001 GR001
0000bac5aeeb GR001 GR001
0000fed5af13 GR001 GR123
0000cba5b187 GR001 GR169
join
é a ferramenta adequada para isso:
join <(sort file1) <(sort file2)
Como funciona em arquivos classificados, estou usando a substituição de processos do bash ( <(...)
) para classificar cada arquivo antes de alimentá-los com join
.