Combinando registros de dois arquivos classificados

4

Eu tenho dois grandes arquivos com mais de seis milhões de registros. Os dados nesses dois arquivos podem ser correlacionados por UID (se encomendar o arquivo, deve estar na mesma linha em ambos os arquivos). Eventualmente eu preciso obter dados do primeiro arquivo concatenado com dados no segundo arquivo.

A questão é que a execução do script leva 10 horas para cerca de 650.000 registros!

Eu gostaria de melhorar isso.

UIDS='cut -f1 -d',' sorted_UID_data1.txt'

for record in $UIDS
do
    echo 'grep $record sorted_UID_data1.txt| awk -F ',' '{print $2}'','grep $record sorted_UID_data2.txt' >> data.txt
done

Para otimizá-lo, pensei em

TOTAL_RECORDS='wc -l < sorted_UID_data1.txt'

recordId=1
while [ $recordId -le $TOTAL_RECORDS ]
do
    echo 'sed -n "${recordId}{p;q;}" sorted_UID_data1.txt| awk -F ',' '{print $2}'','sed -n "${recordId}{p;q;}" sorted_UID_data2.txt' >> data.txt
    recordId=$(( $recordId + 1 ))
done

E isso também está demorando muito tempo.

Mas então, eu estou pensando: E se eu sempre puder pegar a primeira linha do arquivo? Eu vi que isso poderia ser feito por sed , tail , ou AWK , mas isso parece ser ineficiente.

Como posso resolver este problema?

    
por user1977050 27.09.2015 / 11:18

2 respostas

7

Para remover a primeira linha, use tail :

# seq 5 | tail -n +2
2
3
4
5

E apenas para "pegar a primeira linha" use head :

# seq 5 | head -n 1
1

Mas para juntar dois arquivos linha a linha, use paste :

# seq 5 > nums
# echo -e 'a\nb\nc\nd\ne' > chars
# paste nums chars     
1       a
2       b
3       c
4       d
5       e

E para juntar dois arquivos com arquivos comuns correspondentes, use join :

# paste -d , <( seq 5 ) <( seq 11 15 ) > teens
# paste -d , <( seq 5 ) <( seq 21 25 ) > twenties
# join -t , teens twenties
1,11,21
2,12,22
3,13,23
4,14,24
5,15,25
    
por 27.09.2015 / 11:41
4

À medida que você usa o melhor campo-chave, use join

join -t ',' sorted_UID_data1.txt sorted_UID_data2.txt
    
por 27.09.2015 / 12:12