dividindo um CSV e mantendo o cabeçalho sem arquivos intermediários [closed]

3

Estou tentando dividir uma dúzia de arquivos de 100MB ou csv em arquivos menores gerenciáveis para um post de enrolar.

Eu consegui fazer isso, mas com muitos arquivos temporários e IO. Está levando uma eternidade.

Espero que alguém possa me mostrar uma maneira de fazer isso de maneira muito mais eficaz; de preferência com pouco ou nenhum disco IO

#!/bin/sh

for csv in $(ls *.csv); do
    tail -n +2 $csv | split -a 5 -l - $RANDOM.split.
done

# chose a file randomly to fetch the header from   

header=$(ls *.csv |sort -R |tail -1 | cut -d',' -f1)

mkdir split

for x in $(/usr/bin/find . -maxdepth 1 -type f -name '*.split.*'); do
    echo Processing $x
    cat header $x >> split/$x
    rm -f $x
done

O script acima pode não funcionar totalmente. Eu basicamente consegui trabalhar através de uma combinação desses comandos.

Eu decidi fazer o POST curl outra etapa inteiramente no caso de falha de upload; Eu não queria perder os dados se tudo fosse postado. Mas, se, digamos, no erro de enrolar os dados puderem ser colocados em uma pasta de refazer, isso poderá funcionar.

#!/bin/sh

# working on a progress indicator as a percentage. Never finished.
count=$(ls -1 | wc -l 2> /dev/null | cut -d' ' -f1)

for file in $(/usr/bin/find . -maxdepth 1 -type f); do
    echo Processing $file
    curl -XPOST --data-binary @$file -H "Content-Type: text/cms+csv" $1
done
    
por Christian Bongiorno 03.11.2014 / 06:06

1 resposta

4

Uma abordagem totalmente diferente seria usar o paralelo GNU e usar suas opções --header e --pipe :

cat input.csv | parallel --header : --pipe -N 10 'cat > output{#}.csv'

Isso te dará 11 linhas em cada um dos arquivos (a linha de cabeçalho mais os dez de -n 10 , exceto no último arquivo escrito dessa forma).

    
por 03.11.2014 / 08:07