shell-script-pt
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [shell-script] Inserir quebra de l inha a cada N repetições de um pa


From: Julio C. Neves
Subject: Re: [shell-script] Inserir quebra de l inha a cada N repetições de um padrão.
Date: Fri, 29 Jan 2016 16:31:28 -0200

Valeu Rodrigo,
acho que posso afirmar que para trabalhar com registros muito longos o awk dá banho...​

OBS: Pessoal, em abril darei um treinamento no RJ em 2 fins de semana (32 horas) por um preço ridiculamente baixo, porém será no *seu* notebook, *não* darei livros (mas consigo 30% de desconto na compra) e *sem* coffee break. Se alguém estiver a fim, me mande um e-mail em pvt que passo a ementa, explico como, onde e quando será o treinamento e como consegui chegar a esse preço ridículo.​


Abcs,
Julio
@juliobash

P
róximos cursos de Shell
Cidade         Local Período
Rio de Janeiro EDX 05-06/03 e 12-13/03 (Sábados e Domingos)
São Paulo 4Linux 11/04 a 15/04
Dou treinamento de Shell em qualquer cidade.
Para mais detalhes, me mande um e-mail.


Em 29 de janeiro de 2016 12:17, Rodrigo Tenorio address@hidden [shell-script] <address@hidden> escreveu:
 

Peço desculpas ao Fredi, foi ele quem deu a ideia inicial da linha pura em SED.
Reparei que eu acabei citando a pessoa errada em um mail anterior. Foi mal, camarada.

Fico feliz em ajudar, professor.

Testei a linha sem o pipe.
time sed -r "s/[^\(]*(([^\)]+\),){5})/INSERT INTO 'TABLE' VALUES \1;\n/g; s/,;/;/g" teste_sp.sql
real 0m53.932s
user 0m16.788s
sys 0m0.228s

Obs: Novamente houve pausa entre linhas. Estou acreditando que, antes de processar uma linha, o sed carrega um buffer. Sendo uma linha de tamanho "normal" isso passa desapercebido.

Em todo o caso...

Itamar,
Eu não tinha me dado conta desse detalhe desde o início.
As linhas não possuem apenas múltiplos de 5. E devido aos valores demonstrados, não consegui também extrair um denominador comum.
Eu notei o problema apenas no sed. Eu mandei um cat e peguei os últimos registros mostrados para fazer a comparação.

cat teste_sp.sql
,(201004,'Embu','Zurique','Jardim Sergio','06810-540','Rua'),(201005,'São Bernardo do Campo','Zurique','Jardim Uiriçaba','09847-100','Rua'),(201006,'Santo André','Zurique','Parque Capuava','09270-250','Rua'),(201007,'Araras','Zurita','Jardim Belvedere','13601-020','Avenida'),(201008,'São Paulo','Zuzarte','Vila Morumbi','05688-130','Rua'),(201009,'São Paulo','Zuzarte Lopes','Vila Nivi','02252-200','Rua');

Desta vez o ultimo registro do cat bateu com o ultimo do SED, mas o resultado do SED ficou assim [as duas ultimas linhas]:
INSERT INTO 'TABLE' VALUES (201004,'Embu','Zurique','Jardim Sergio','06810-540','Rua'),(201005,'São Bernardo do Campo','Zurique','Jardim Uiriçaba','09847-100','Rua'),(201006,'Santo André','Zurique','Parque Capuava','09270-250','Rua'),(201007,'Araras','Zurita','Jardim Belvedere','13601-020','Avenida'),(201008,'São Paulo','Zuzarte','Vila Morumbi','05688-130','Rua');
(201009,'São Paulo','Zuzarte Lopes','Vila Nivi','02252-200','Rua');

Observação:
> O estranho que na contagem da linha 16 há 4987 registros. No meu pensamento, mesmo que errado, a ultima linha deveria possuir dois registros separados por vírgula.

Verifiquei também o AWK novamente, mesmo comando já citado, e com ele eu tive o resultado que eu calculei nas ultimas linhas; cinco registros na penúltima linha e dois na ultima:

INSERT INTO 'TABLE' VALUES (201003,'Avaré','Zurique','Jardim Europa II','18707-610','Rua'),(201004,'Embu','Zurique','Jardim Sergio','06810-540','Rua'),(201005,'São Bernardo do Campo','Zurique','Jardim Uiriçaba','09847-100','Rua'),(201006,'Santo André','Zurique','Parque Capuava','09270-250','Rua'),(201007,'Araras','Zurita','Jardim Belvedere','13601-020','Avenida');
INSERT INTO 'TABLE' VALUES (201008,'São Paulo','Zuzarte','Vila Morumbi','05688-130','Rua'),(201009,'São Paulo','Zuzarte Lopes','Vila Nivi','02252-200','Rua');

O tempo foi ainda menor do que ontem...
real 0m42.455s
user 0m1.116s
sys 0m0.288s

Segue a contagem de registros por linha do arquivo original:

awk -F '[)],[(]' '{ print NR, NF}' teste_sp.sql1 13585
2 12976
3 13328
4 13298
5 13160
6 12635
7 13026
8 13237
9 12539
10 12880
11 12922
12 13171
13 12652
14 13234
15 13379
16 4987
17 0

Em sex, 29 de jan de 2016 às 10:32, 'Julio C. Neves' address@hidden [shell-script] <address@hidden> escreveu:
 

Acho estes testes muito úteis para os apreciadores de shell da lista.

Qdo te pedir para testar, não havia reparado o pipe e outra chamada do sed, o que realmente deve dar uma destorcida na avaliação. Te peço o favor de também publicar aqui
a proposta do Itamar, que eliminou o "| sed" e foi a seguinte:

$ time sed -r "s/[^\(]*(([^\)]+\),){5})/INSERT INTO 'TABLE' VALUES \1;\n/g; s/,;/;/g" teste_sp.sql

OBS: Pessoal, em abril darei um treinamento no RJ em 2 fins de semana (32 horas) por um preço ridiculamente baixo, porém será no *seu* notebook, *não* darei livros (mas consigo 30% de desconto na compra) e *sem* coffee break. Se alguém estiver a fim, me mande um e-mail em pvt que explico como,onde e quando será e como consegui chegar a esse preço ridículo.


Abcs,
Julio
@juliobash

P
róximos cursos de Shell
Cidade         Local Período
Rio de Janeiro EDX 05-06/03 e 12-13/03 (Sábados e Domingos)
São Paulo 4Linux 11/04 a 15/04
Dou treinamento de Shell em qualquer cidade.
Para mais detalhes, me mande um e-mail.


Em 29 de janeiro de 2016 00:21, Rodrigo Tenorio address@hidden [shell-script] <address@hidden> escreveu:
 

Kkkkkkk
É tão difícil que fiquei até com vergonha de não saber...

Direto ao ponto:
SED puro:
time sed -r "s/[^\(]*(([^\)]+\),){5})/\1;\n/g; s/,;/;/g" teste_sp.sql | sed "s/^/INSERT INTO 'TABLE' VALUES /g"
real 0m52.688s
user 0m17.208s
sys 0m0.356s

AWK puro:
time awk -F '[)],[(]' '{for (i=1;i<=NF;i++) printf (i>1?"(" $i:$i) (i<NF?")":"") (i%5==0 && i<NF?";\nINSERT INTO '\''TABLE'\'' VALUES ":(i<NF?",":"\n"))}' teste_sp.sql
real 0m43.486s
user 0m0.944s
sys 0m0.332s

Professor,
Tentei prever o máximo de info que talvez fosse relevante, mas se precisar de mais alguma coisa é só falar.

Observações:
> O arquivo original possui dezesseis linhas;
> Para cada linha o SED apresentou uma pausa de aproximadamente um segundo, não consegui contabilizar isso direito;
> O AWK não apresentou pausa alguma. Foi direto até o final.
> Com o redirecionamento de saída para arquivo " >> cep_sp_data_dump.sql" o AWK foi quase instantâneo;
> O SED levou um tempo consideravelmente maior [talvez por culpa do pipe???];
> O gEdit leva aproximadamente quatro minutos para abrir o arquivo original de 15MB em 16 linhas;
> Já o arquivo resultante é aberto em menos de um minuto e tem mais de 40k linhas em 17MB;
> O arquivo do SED ficou 300kb menor que o do AWK, verifiquei que os últimos registros não foram criados corretamente. a ultima linha só teve o "insert .... value";

Seguem infos do meu pc:
RAM: 8GB

lscpu
Arquitetura:           x86_64
Modo(s) operacional da CPU32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                4
On-line CPU(s) list:   0-3
Thread(s) per núcleo  2
Núcleo(s) por soquete:2
Soquete(s):            1
Nó(s) de NUMA:        1
ID de fornecedor:      GenuineIntel
Família da CPU:       6
Modelo:                37
Step:                  5
CPU MHz:               933.000
BogoMIPS:              5054.83
Virtualização:       VT-x
cache de L1d:          32K
cache de L1i:          32K
cache de L2:           256K
cache de L3:           3072K
NUMA node0 CPU(s):     0-3


Em qui, 28 de jan de 2016 às 22:00, 'Julio C. Neves' address@hidden [shell-script] <address@hidden> escreveu:
 

Como em shell tudo é muito difícil de fazer, para medir os tempos de execução não poderia ser diferente. Vc t de colocar o cmd time do awk e antes do sed, ou seja:
    time awk ...
e
    time sed ...
Viu como é difícil.  ;)

Em 28/01/2016 9:48 PM, "Rodrigo Tenorio address@hidden [shell-script]" <address@hidden> escreveu:
 

Não vejo problemas em testar, professor.

Mas não tenho ideia de como posso realizar o teste.
Andei procurando no google e só achei coisas relativas a benchmark e teste de velocidade de conexão.

O que devo fazer para realizar o teste?

Em qui, 28 de jan de 2016 às 08:32, address@hidden [shell-script] <address@hidden> escreveu:
 

Desculpe...


Copiei código errado...
O código puro em awk seria esse:

$ awk -F '[)],[(]' '{for (i=1;i<=NF;i++) printf (i>1?"(" $i:$i) (i<NF?")":"") (i%5==0 && i<NF?";\nINSERT INTO '\''TABLE'\'' VALUES ":(i<NF?",":"\n"))}' arquivo.sql

[]'s
Itamar




reply via email to

[Prev in Thread] Current Thread [Next in Thread]