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

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

Re: [shell-script] Contar número de campos de uma linha


From: Rodrigo Boechat
Subject: Re: [shell-script] Contar número de campos de uma linha
Date: Sun, 14 Aug 2011 10:44:29 -0300
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:5.0) Gecko/20110627 Thunderbird/5.0

Robson, bom dia.

Sua única linha de awk me compeliu a pesquisar mais...
^_^
Usei o mesmo arquivo da pasta tmp que você criou e fiz o seguinte 
comando de sed:
sed -e '/^\([0-9]*\*\)\{4\}/d' -e 's/\(.\{29\}\)/\1\*/' /tmp/arquivo.txt

Bom. Por causa deste tópico eu tive que aprender regex e a mexer com sed.
Por isso vou explicar aqui a linha. É bom que fica de conteúdo pra mim 
depois.
:)

Explicando a linha:
A primeira parte do comando sed -e '/^\([0-9]*\*\)\{4\}/d' emula um 
"egrep -v". Então ele procura por linhas que não se enquadrem na 
seguinte estrutura [numeros]*[numeros]*[numeros]*[numeros]*
Com isso ela retorna a seguinte resposta:

1996062519*20110523*11443600*1,00*0,36*LINHA TESTE*LINHA TESTE
1996062519*20110523*11443600*1,00*0,36*LINHA TESTE2*LINHA TESTE2
1996062519*20110523*11443600*1,00*0,36*LINHA TESTE3*LINHA TESTE3

Porque se repararmos, o quarto campo possui o número 1 seguido de 
vírgula, não de asterisco.

Já a segunda parte: -e 's/\(.\{29\}\)/\1\*/'
Conta 29 caracteres e insere o asterisco na posição.
Também essa parte poderia ser escrita da seguinte forma:
-e 's/\(\([0-9]*\*\)\{3\}\)/\1\*/'

Fica assim: sed -e '/^\([0-9]*\*\)\{4\}/d' -e 
's/\(\([0-9]*\*\)\{3\}\)/\1\*/' /tmp/arquivo.txt
Testei e funcionou...

O resultado final é o desejado por Mauricy e sem o limite de quantidade 
fixa de caracteres:
1996062519*20110523*11443600**1,00*0,36*LINHA TESTE*LINHA TESTE
1996062519*20110523*11443600**1,00*0,36*LINHA TESTE2*LINHA TESTE2
1996062519*20110523*11443600**1,00*0,36*LINHA TESTE3*LINHA TESTE3

Tiago,
Acho que fui um tanto ríspido contigo no email anterior. Me desculpe.

Bem, caro Mauricy.
Agora é só escolher qual das opções você quer usar.
E dá algum retorno, né?

Rodrigo Boechat



Em 14-08-2011 02:52, Robson Alexandre escreveu:
> Caro Mauricy e demais colegas da lista
>
> acho que esta solução serve para vc independente do numero de caracteres de
> cada campo, utilizando awk 1line
>
> #http://ideone.com/qpLCq
> #!/bin/bash
> (
> cat<<  EOF
> 1996062519*20110530*08312100*1996062515*0,70*0,00*CHAMADA LOCAL*UTILIZAÇÃO
> ACIMA DO CONTRATADO
> 1996062519*20110602*09402000*1996062528*7,80*0,00*CHAMADA LOCAL*UTILIZAÇÃO
> ACIMA DO CONTRATADO
> 1996062519*20110602*10291200*1996062510*16,50*0,00*CHAMADA LOCAL*UTILIZAÇÃO
> ACIMA DO CONTRATADO
> 1996062519*20110515*18024600*1996062511*1,00*0,21*TORPEDO VIVO
> FLEXIVE*UTILIZAÇÃO ACIMA DO CONTRATADO
> 1996062519*20110523*11443600*1,00*0,36*LINHA TESTE*LINHA TESTE
> 1996062519*20110507*10470400**1,00*2,21*SINCRONISMO INICIAL*UTILIZAÇÃO ACIMA
> DO CONTRATADO
> 1996062519*20110523*11443600**1,00*0,36*ATUALIZACAO AGENDA*UTILIZAÇÃO ACIMA
> DO CONTRATADO
> 1996062519*20110515*18024600*1996062511*1,00*0,21*TORPEDO VIVO
> FLEXIVE*UTILIZAÇÃO ACIMA DO CONTRATADO
> 1996062519*20110523*11443600*1,00*0,36*LINHA TESTE2*LINHA TESTE2
> 1996062519*20110530*08312100*1996062515*0,70*0,00*CHAMADA LOCAL*UTILIZAÇÃO
> ACIMA DO CONTRATADO
> 1996062519*20110602*09402000*1996062528*7,80*0,00*CHAMADA LOCAL*UTILIZAÇÃO
> ACIMA DO CONTRATADO
> 1996062519*20110602*10291200*1996062510*16,50*0,00*CHAMADA LOCAL*UTILIZAÇÃO
> ACIMA DO CONTRATADO
> 1996062519*20110523*11443600*1,00*0,36*LINHA TESTE3*LINHA TESTE3
> EOF
> )>  /tmp/arquivo.txt
>
> awk -F* 'OFS="*" { if ( NF=="8" ) {print $0 } else print
> $1,$2,$3,"",$4,$5,$6,$7 }' /tmp/arquivo.txt
>
> Resultado:
>
> 1996062519*20110530*08312100*1996062515*0,70*0,00*CHAMADA
> LOCAL*UTILIZAÇÃO ACIMA DO CONTRATADO
> 1996062519*20110602*09402000*1996062528*7,80*0,00*CHAMADA
> LOCAL*UTILIZAÇÃO ACIMA DO CONTRATADO
> 1996062519*20110602*10291200*1996062510*16,50*0,00*CHAMADA
> LOCAL*UTILIZAÇÃO ACIMA DO CONTRATADO
> 1996062519*20110515*18024600*1996062511*1,00*0,21*TORPEDO VIVO
> FLEXIVE*UTILIZAÇÃO ACIMA DO CONTRATADO
> 1996062519*20110523*11443600**1,00*0,36*LINHA TESTE*LINHA TESTE
> 1996062519*20110507*10470400**1,00*2,21*SINCRONISMO INICIAL*UTILIZAÇÃO
> ACIMA DO CONTRATADO
> 1996062519*20110523*11443600**1,00*0,36*ATUALIZACAO AGENDA*UTILIZAÇÃO
> ACIMA DO CONTRATADO
> 1996062519*20110515*18024600*1996062511*1,00*0,21*TORPEDO VIVO
> FLEXIVE*UTILIZAÇÃO ACIMA DO CONTRATADO
> 1996062519*20110523*11443600**1,00*0,36*LINHA TESTE2*LINHA TESTE2
> 1996062519*20110530*08312100*1996062515*0,70*0,00*CHAMADA
> LOCAL*UTILIZAÇÃO ACIMA DO CONTRATADO
> 1996062519*20110602*09402000*1996062528*7,80*0,00*CHAMADA
> LOCAL*UTILIZAÇÃO ACIMA DO CONTRATADO
> 1996062519*20110602*10291200*1996062510*16,50*0,00*CHAMADA
> LOCAL*UTILIZAÇÃO ACIMA DO CONTRATADO
> 1996062519*20110523*11443600**1,00*0,36*LINHA TESTE3*LINHA TESTE3
>
> http://ideone.com/qpLCq
>
> Atenciosamente
>
> Robson Alexandre
>
> Em 10 de agosto de 2011 20:17, Rodrigo Boechat<
> address@hidden>  escreveu:
>
>> **
>>
>>
>> Tiago, olá!
>>
>> Como disse, se os campos possuírem quantidades de caracteres fixos a
>> solução que eu fiz vai servir.
>> Só pra constar. Eu mandei apenas a expressão chave para o interessado se
>> manifestar, correr atrás e voltar com dúvidas.
>> Mas...
>> Segue o link: http : / / pastebin . com / D5tC7w9X
>>
>> Se não me engano, tem como fazer isso com apenas uma linha de sed.
>>
>> Rodrigo Boechat
>>
>> Em 10-08-2011 15:47, Tiago Peczenyj escreveu:
>>
>>> ola rodrigo
>>>
>>> sua solução parece boa porém seria interessante que a mesma viesse sob
>> forma
>>> de testes.
>>>
>>> por exemplo, vc pode usar o paste bin para "provar" que a sua solução é
>> boa
>>> ao fazer algo como
>>>
>>> $ cat exemplo.txt
>>> ...
>>>
>>> $ grep -opcoes 'expressão regular' exemplo.txt
>>> ...
>>>
>>>
>>> via algum pastebin.com da vida
>>>
>>> sigo isso pq posso não estar no mesmo sistema operacional que vc, ou
>> mesmo
>>> shell ou opçoes de localização. se vc me mostrar que funciona "para vc"
>>> provavelmente vai funcionar para todos, caso contrario podemos debater
>> sobre
>>> as possiveis diferenças e todo mundo sai ganhando.
>>>
>>> imagine que vc ache uma solução que só rode bem em um ksh de um HP-UX, é
>>> interessante saber mais sobre isso.
>>>
>>> 2011/8/10 Rodrigo Boechat<address@hidden>
>>>
>>>> **
>>>>
>>>>
>>>> Eu vi outro tipo de solução possível para sua questão.
>>>> Considerei que os campos que você citou possuem quantidade de caracteres
>>>> definida.
>>>> 10*8*8*10*....
>>>> Como é o quarto campo que importa, segundo seu relato, fiz uma expressão
>>>> simples de ser entendida.
>>>> ^[0-9]{10}\*[0-9]{8}\*[0-9]{8}\*([0-9]{10}|\*)
>>>> Basicamente é só você testar quais as linhas que não se enquadram nessa
>>>> expressão com egrep e inserir os campos vazios.
>>>>
>>>> Espero ter ajudado.
>>>>
>>>> Rodrigo Boechat
>>>>
>>>> Em 10-08-2011 11:29, Valtoir escreveu:
>>>>
>>>>> Adaptado de um exemplo do MrBits, na lista:
>>>>>
>>>>> cat arquivo | while read linha; do IFS="*"; set - $linha; echo $#; done
>>>>>
>>>>> Valtoir
>>>>>
>>>>> Em 10 de agosto de 2011 10:55, Fabricio Mattos<address@hidden
>>>>> <mailto:fabrimatt%40gmail.com>>  escreveu:
>>>>>> Realmente, entendi que ele queria contar os caracteres
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> Em 10 de agosto de 2011 10:40, Tiago Peczenyj
>>>>>> <address@hidden<mailto:tiago.peczenyj%40gmail.com
>>>>>> escreveu:
>>>>>>> **
>>>>>>>
>>>>>>>
>>>>>>> fabricio, dessa forma vc calcularia o numero de caracteres e não de
>>>>>>> campos separador pelo caracter *
>>>>>>>
>>>>>>> 2011/8/10 Fabricio Mattos<address@hidden
>>>>> <mailto:fabrimatt%40gmail.com>>:
>>>>>>>> wc -c nome_do_ARQUIVO
>>>>>>>>
>>>>>>>> Em 10 de agosto de 2011 10:16, Mauricy Maiorino
>>>>>>>> <address@hidden
>>>>> <mailto:mauricym%40ccuec.unicamp.br>>escreveu:
>>>>>>>>> **
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Pessoal
>>>>>>>>>
>>>>>>>>> Preciso "contar" o número de campos de uma linha de um arquivo no
>>>>>>> formato:
>>>>>>>>> 1996062519*20110530*08312100*1996062515*0,70*0,00*CHAMADA
>>>>>>>>> LOCAL*UTILIZAÇÃO ACIMA DO CONTRATADO
>>>>>>>>> 1996062519*20110602*09402000*1996062528*7,80*0,00*CHAMADA
>>>>>>>>> LOCAL*UTILIZAÇÃO ACIMA DO CONTRATADO
>>>>>>>>> 1996062519*20110602*10291200*1996062510*16,50*0,00*CHAMADA
>>>>>>>>> LOCAL*UTILIZAÇÃO ACIMA DO CONTRATADO
>>>>>>>>> 1996062519*20110515*18024600*1996062511*1,00*0,21*TORPEDO VIVO
>>>>>>>>> FLEXIVE*UTILIZAÇÃO ACIMA DO CONTRATADO
>>>>>>>>> 1996062519*20110507*10470400**1,00*2,21*SINCRONISMO
>>>>> INICIAL*UTILIZAÇÃO
>>>>>>>>> ACIMA DO CONTRATADO
>>>>>>>>> 1996062519*20110523*11443600**1,00*0,36*ATUALIZACAO
>>>>> AGENDA*UTILIZAÇÃO
>>>>>>>>> ACIMA DO CONTRATADO
>>>>>>>>>
>>>>>>>>> o arquivo "tem" que conter 8 campos por linha. Preciso que o
>>>>> numero de
>>>>>>>>> campos seja retornado para que quando a linha contiver, no caso,
>>>>> menos
>>>>>>>>> que 8 campos ele execute determinada ação(incluir um campo em
>>>> branco
>>>>>>>>> após o terceiro campo). Os campos são separados por *.
>>>>>>>>>
>>>>>>>>> Não sei como pegar este valor!!
>>>>>>>>>
>>>>>>>>> Obrigado
>>>>>>>>>
>>>>>>>>> Mauricy
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>> [As partes desta mensagem que não continham texto foram removidas]
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> ------------------------------------
>>>>>>>>
>>>>>>>> ----------------------------------------------------------
>>>>>>>> Esta lista não admite a abordagem de outras liguagens de
>>>> programação,
>>>>>>> como perl, C etc. Quem insistir em não seguir esta regra será
>>>>> moderado sem
>>>>>>> prévio aviso.
>>>>>>>> ----------------------------------------------------------
>>>>>>>> Sair da lista: address@hidden
>>>>> <mailto:shell-script-unsubscribe%40yahoogrupos.com.br>
>>>>>>>> ----------------------------------------------------------
>>>>>>>> Esta lista é moderada de acordo com o previsto em
>>>>>>> http://www.listas-discussao.cjb.net
>>>>>>>> ----------------------------------------------------------
>>>>>>>> Servidor Newsgroup da lista: news.gmane.org
>>>>>>>> Grupo: gmane.org.user-groups.programming.shell.brazil
>>>>>>>>
>>>>>>>> Links do Yahoo! Grupos
>>>>>>>>
>>>>>>>>
>>>>>>> --
>>>>>>> Tiago B. Peczenyj
>>>>>>> Linux User #405772
>>>>>>>
>>>>>>> http://pacman.blog.br
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>> [As partes desta mensagem que não continham texto foram removidas]
>>>>>>
>>>>>>
>>>>>>
>>>>>> ------------------------------------
>>>>>>
>>>>>> ----------------------------------------------------------
>>>>>> Esta lista não admite a abordagem de outras liguagens de
>>>>> programação, como perl, C etc. Quem insistir em não seguir esta regra
>>>>> será moderado sem prévio aviso.
>>>>>> ----------------------------------------------------------
>>>>>> Sair da lista: address@hidden
>>>>> <mailto:shell-script-unsubscribe%40yahoogrupos.com.br>
>>>>>> ----------------------------------------------------------
>>>>>> Esta lista é moderada de acordo com o previsto em
>>>>> http://www.listas-discussao.cjb.net
>>>>>> ----------------------------------------------------------
>>>>>> Servidor Newsgroup da lista: news.gmane.org
>>>>>> Grupo: gmane.org.user-groups.programming.shell.brazil
>>>>>>
>>>>>> Links do Yahoo! Grupos
>>>>>>
>>>>>>
>>>>>>
>>>> [As partes desta mensagem que não continham texto foram removidas]
>>>>
>>>>
>>>>
>>>
>> [As partes desta mensagem que não continham texto foram removidas]
>>
>>
>>
>
> [As partes desta mensagem que não continham texto foram removidas]
>
>
>
> ------------------------------------
>
> ---------------------------------------------------------------------
> Esta lista não admite a abordagem de outras liguagens de programação, como 
> perl, C etc. Quem insistir em não seguir esta regra será moderado sem prévio 
> aviso.
> ---------------------------------------------------------------------
> Sair da lista: address@hidden
> ---------------------------------------------------------------------
> Esta lista é moderada de acordo com o previsto em 
> http://www.listas-discussao.cjb.net
> ---------------------------------------------------------------------
> Servidor Newsgroup da lista: news.gmane.org
> Grupo: gmane.org.user-groups.programming.shell.brazil
>
> Links do Yahoo! Grupos
>
>
>


[As partes desta mensagem que não continham texto foram removidas]



reply via email to

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