divide arquivos csv sem manter o csv original

0

Eu tenho um arquivo CSV grande e quero dividi-lo em pequenos blocos. Eu sei que posso dividir o arquivo CSV usando

split -l 1000000 file.csv new

que resulta em uma parte com linhas de 1000000.Mas o problema é que ele divide, mas também o original existe. Desde que eu não tenho muito espaço no meu disco existe alguma maneira de dividir o CSV sem manter o original? Qualquer ajuda é apreciada. Agradecemos antecipadamente.

    
por joker21 29.11.2016 / 04:01

3 respostas

1

Uma maneira de fazer isso, assumindo o GNU stat(1) e o GNU truncate(1) :

#! /bin/sh

lines=1000000

size=$( wc -l "$1" | awk '{print $1}' )
tail=$(( size % lines ))
count=$(( size / lines ))

if [ $tail -ne 0 ]; then
    let count++
fi           

while [ $count -gt 0 ]; do
    start=$(( (count - 1) * lines + 1 ))
    fn=$( printf '%s_%05d' "$1" $count )
    sed -n $start,\$p <"$1" >"$fn"
    size_last=$( stat -c %s "$fn" )
    truncate -s -$size_last "$1"
    let count--
done

Sem o GNU coreutils , a mesma coisa poderia ser feita em Perl.

O arquivo original se perde no processo, portanto, é aconselhável testar primeiro os arquivos acima com alguns arquivos menores, com lines definido para, digamos, 100.

    
por 29.11.2016 / 07:49
1

Se a memória em seu sistema for grande o suficiente para armazenar todo o arquivo csv , você poderia tentar essa maneira muito perigosa de colocar o arquivo em um sistema de arquivos temporário (por exemplo, um disco rígido virtual na sua RAM) e, em seguida, comece a dividi-lo a partir do disco rígido.

Observe que quando o computador é desligado enquanto o arquivo está nesse tmpfs , os dados serão perdidos ! Isso é muito, muito propenso a fazer você infeliz.

Normalmente /dev/shm já deve estar presente, verifique se mount | grep shm lista tmpfs como montado em /dev/shm , e então:

mv file /dev/shm
split -l 1000000 /dev/shm/file /path/to/split/directory/

Eu não sei quanto excesso de memória você precisará além do tamanho do arquivo, já que não estou familiarizado com o uso de memória de split , mas seria pelo menos um milhão de linhas que você está dividindo, Eu assumo.

Novamente esteja preparado para perda de dados em uma queda de energia simples ou algo inesperado.

PS: Talvez você tenha uma unidade flash USB à mão para usar como seu sistema de arquivos temporários - menos perigoso, mas mais lento.

    
por 29.11.2016 / 09:01
-1

Se não houver problema em reverter a ordem dos campos CSV, você pode tentar algo nas seguintes linhas:

SIZ=$(stat -c %s input)
tac input |\
(
  IFS=""
  while read -r LINE
  do
    ADJ=${#LINE}
    SIZ=$(( (SIZ-ADJ-1) ))
    truncate -s $SIZ input
    echo "$LINE"
  done
) |\
split -l 10 - output

Também levará mais tempo para ser executado do que um comando split simples, mas talvez não muito mais.

Economiza espaço em disco, permitindo que ele seja executado mesmo se o arquivo inicial ocupar quase 100% do espaço disponível em disco.

Você desejará alterar os nomes dos arquivos e aumentar o argumento -l 10 para split . Eu postei do jeito que testei, em um arquivo com menos de um milhão de linhas.

    
por 29.11.2016 / 04:42

Tags