Dividindo arquivo baseado no último dígito da primeira coluna no UNIX

2

Eu tenho um arquivo sales_$date.csv . Eu quero dividi-lo em 10 arquivos com base no último dígito da primeira coluna (ITEM). então, na realidade, o arquivo seria dividido em 10 arquivos como sales_$date-01.csv , sales_$date-02.csv , e assim por diante. Também preciso manter o cabeçalho em todos os arquivos. O comprimento para o valor da coluna (ITEM) não é fixo. Esse processo precisa ser executado a cada: 45 minutos todos os dias. Abaixo está o exemplo

arquivo sales_ $ date.csv : FILE = sales_ $ date     ITEM, QTY, LOJA, BUYABLEFLAG     4000,1,13805, Y     4001,3,1456, N     5010,2, 14534, Y     7200,5,14566, N     4002,2,6534534, N     5611,9,34234, Y     7832,32,6575, N

sales_ $ date-01.csv deve ter os registros dos itens (veja o valor da primeira coluna ITEM) terminando com 0:

ITEM,QTY,STORE,BUYABLEFLAG
4000,1,13805,Y
5010,2,14534,Y
7200,5,14566,N

sales_ $ date-02.csv deve ter os registros de itens (veja o valor da primeira coluna ITEM) terminando com 1:

ITEM,QTY,STORE,BUYABLEFLAG
4001,3,1456,N
5611,9,34234,Y

sales_ $ date-03.csv deve ter os registros de itens (veja o valor da primeira coluna ITEM) terminando com 2:

ITEM,QTY,STORE,BUYABLEFLAG
4002,2,6534534,N
7832,32,6575,N

Além disso, todos os nomes de arquivo, por exemplo sales_date-01, sales_date-02 e sales_date-03, estão em uma variável chamada FILE_NAME.

    
por saurabh 31.03.2016 / 16:14

3 respostas

4

Se o seu arquivo é apenas grande, não gigantesco, você pode fazer 10 passagens pelo arquivo com:

for digit in 0 1 2 3 4 5 6 7 8 9 ; do
    egrep "^ITEM,|^...$digit" sales.csv >sales-0$digit.csv
done
    
por 31.03.2016 / 17:47
3

Em uma única passagem:

awk '
    NR == 1 { for (i=1; i<=10; i++) print > sprintf("sales-%02d.csv", i) }
    NR > 1  { print > sprintf("sales-%02d.csv", $1%10+1) }
' data
    
por 31.03.2016 / 22:25
0

Eu quebraria o perl para isso - é um pouco mais detalhado, mas espero que seja mais claro o que está fazendo? Ele funciona como passagem única, analisa o 'id' da linha e abre um arquivo baseado nele. Na verdade, ele não cria arquivos, que de outra forma estariam vazios - eu chamaria isso de recurso, mas é fácil mudar se você não gostar dele.

#!/usr/bin/perl
use strict;
use warnings;

#read header row from STDIN or file specified on command line (like grep/sed/awk)
my $header = <>; 

#set up file handles to write to 
my %file_for; 

#iterate STDIN or files on command line
while ( <> ) { 
    #get 'first digit before a comma' on current line. 
    my ( $file_id ) = /(\d),/;

    #open the file, if we haven't already. (it auto closes at script exit)
    if ( not defined $file_for{$file_id} ) {
        open ( $file_for{$file_id}, '>', "sales-0".$file_id.".csv" ) or warn $!;
        #print the header row
        print {$file_for{$file_id}} $header;
    }
    #select this file for output, and print the current line. 
    select $file_for{$file_id} and print;
}
    
por 01.04.2016 / 11:55