Reindexar um arquivo CSV grande

11

Eu passei pelas respostas em este tópico útil , mas o meu problema parece ser diferente o suficiente para que eu não consiga pensar em uma boa resposta (pelo menos com sed ).

Eu tenho um arquivo CSV grande (mais de 200 GB) com linhas semelhantes às seguintes:

<alphanumerical_identifier>,<number>

em que <alphanumerical_identifier> é exclusivo em todo o arquivo. Gostaria de criar um arquivo separado que substitua a primeira coluna por um índice , ou seja,

<index>,<number>

para que possamos obter:

1, <number>
2, <number>
3, <number>

Pode awk gerar um índice crescente sem carregar o arquivo completo na memória?

Como o índice aumenta monotonicamente, pode ser ainda melhor apenas eliminar o índice. A solução para isso seria diferente ?, ou seja:

<number>
<number>
<number>
    
por Amelio Vazquez-Reina 18.09.2014 / 20:34

2 respostas

13

Não perto de um terminal para testar, mas que tal o comando nl frequentemente ignorado? Algo como:

cut -f 2 -d , original.csv | nl -w 1 -p -s , > numbered.csv

    
por 18.09.2014 / 21:52
7

Aqui estão algumas abordagens, mas nenhuma abordará a velocidade da solução cut e nl acima:

  1. awk

    awk -F, '{$1=NR;print $1","$2;}' file.csv > newfile.csv
    
  2. Perl

    perl -pe 's/[^,]+/$./' file.csv > newfile.csv
    

    ou

    perl -F, -ane '$F[0]=$.; print join ",", @F' file.csv
    
  3. Shell (mas eu não recomendo para um arquivo de 200G, levará muito tempo)

    i=1; while IFS=, read foo num; do 
            printf "%d,%s\n" $((i++)) $num; 
    done < file.csv > newfile.csv
    

As soluções acima são classificadas por ordem de velocidade. Eu testei no meu laptop e um arquivo de 40M e eles levaram (média de 10 corridas) 2.2282 (awk), 2.4555 (1º perl), 3.1825s (2 perl) e um enorme 48.6035s para o shell. A solução muito inteligente cut e nl que você já tem era cerca de 4 vezes mais rápida em 0.6078s.

    
por 19.09.2014 / 01:49

Tags