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

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

Re: [shell-script] pegar um trecho


From: Julio C. Neves
Subject: Re: [shell-script] pegar um trecho
Date: Fri, 4 Dec 2009 00:10:38 -0200

Fala Fabiano,
Como eu sabia que vc não ia me negar o favor de publicar a sua solução, vou
apresentar aqui uma cópia do que escrevi no changelog da 8a. edição:
  Inserir após último exemplo do eval:

Um dos participantes da lista de *Shell-**script* do Yahoo, disse que tinha
um arquivo chamado dados.txt, cuja linha era assim:

Model=Samsung 0411N, Serial=00000005464, blablabla=asdadqddq


 Porém deste, só interessava o nome do modelo (Samsung 0411N).

As soluções apresentadas foram as mais variadas possíveis (como todas
daquela excelente lista, que aconselho a todos se inscreverem). Veja só
algumas, para que sirvam como exemplo:

*$ cut -f1 -d, dados.txt | cut -f2 -d=*


 Só mais umazinha:

*$ sed -n 's/Model=\([^,]*\).*$/\1/p' dados.txt*


 O Fabiano Caixeta Duarte, grande conhecedor de Bash, deu a seguinte
solução, desculpando-se pela mesma ser deselegante:

*$ Linha=$(<dados.txt)*

*$ Linha=${Linha// /_}*

*$ eval ${Linha%%,*}*

*$ echo ${Model//_/ }*

Samsung 0411N


 Escrevi imediatamente para a lista, dizendo que a solução não tinha nada de
deselegante, muito pelo contrário, pois usava Bash puro e que, por isso,
deveria ser muito mais eficiente e veloz que todas as soluções apresentadas.
Vou explicá-la linha-a-linha:

linha 1 - Carrega todo o arquivo dados.txt para a variável $Linha;

linha 2 - Para não ter problemas na linha 3, esta substituição de parâmetros
troca os espaços por sublinha (_);

linha 3 - Esta substituição de parâmetros despreza tudo à direita da
primeira virgula (,). Observe o que acontece se trocarmos o eval por echo:

* $ echo ${Linha%%,*}*

 Model=Samsung_0411N

  Ou seja: uma atribuição, porém com um sublinha (_) onde havia um espaço em
branco. O eval, efoi usado para que esta atribuição fosse feita. Veja este
teste após a execução desta linha:

* $ echo $Model *

 Samsung_0411N

 linha 4 - Pronto! Agora só falta trocar o sublinha (_) por um espaço em
branco, e foi isso que a substituição de parâmetros desta linha fez.

Abraços,
Julio
Cursos de Shell e Zenity em 2 fins de semana?
- Em SP ligue (11) 2125-4747 Curso de 07 a 11/12;
- Em DF ligue (61) 3223-3000 Curso de zenity 09-10/01;
- No RJ ligue (21) 2561-0867. Curso nos dias 5,6,12,13/12;
- Turmas fechadas em outras cidades ligue (21) 8112-9988.


2009/12/3 Fabiano Caixeta Duarte <address@hidden>

>
>
> 2009/12/2 Julio C. Neves <address@hidden <julio.neves%40gmail.com>
> >:
>
> > Pô Fabiano,
> > essa foi demais!!! Grande sacada!!! Quem te disse que não é elegante?
> > Elegantíssimo...
> >
> > Achei a sacada do eval fantástica. Se vc não se incomodar, vou botar este
> > exemplo no meu livro.
> >
> > Se não fosse o uso do eval, poderia assegurar que esta solução é bem mais
> > rápida que a que fiz usando sed, mas assim mesmo ainda acho que deve ser
> > mais veloz. Será que o dono do arquivo pode testar isso e postar na
> lista?
> >
> > Fabiano aproveite e explique para o pessoal da lista a tua solução pq
> muita
> > gente não deve ter entendido.
> >
> > Abraços,
> > Julio
> > Cursos de Shell e Zenity em 2 fins de semana?
> > - Em SP ligue (11) 2125-4747 Curso de 07 a 11/12;
> > - Em DF ligue (61) 3223-3000 Curso de zenity 09-10/01;
> > - No RJ ligue (21) 2561-0867 Curso nos dias 5,6,12,13/12;
> > - Turmas fechadas em outras cidades ligue (21) 8112-9988.
> >
> >
> > 2009/12/1 Fabiano Caixeta Duarte <address@hidden<fcd.listas%40gmail.com>
> >
> >
> >>
> >>
> >> 2009/12/1 Jeferson Santos <address@hidden<jefersondossantos%40gmail.com>
> <jefersondossantos%40gmail.com>
>
> >> >:
> >> > Olá Lista,
> >> > Tenho uma linha que é mais ou menos assim:
> >> >
> >> > Model=Samsung 0411N, Serial=00000005464, blablabla=asdadqddq
> >> >
> >> > Acontece que eu quero pegar apenas o modelo exato, que seria "Samsung
> >> > 0411N".
> >> > Atualmente eu faço sed 's/Model=//;s/,.*$//'
> >> > Mas sei que com sed tem como eu ser mais elegante que isso e pegar o
> que
> >> > fica entre Model= e a virgula, mas sem pegar elas.
> >> >
> >> > Podem me ajudar?
> >> >
> >> > Abraços
> >> >
> >> >
> >> >
> >> > --
> >> > Abraços,
> >> > Jeferson Santos
> >> >
> >> >
> >>
> >> Não é elegante, mas é bash-only ;)
> >>
> >> linha=$(<arquivo); linha=${linha// /_};eval ${linha%%,*}; echo
> ${Model//_/
> >> }
> >>
> >> Se não houvesse espaços, ficaria mais simples:
> >> linha=$(<arquivo); eval ${linha%%,*}; echo $Model
> >>
> >> --
> >> Fabiano Caixeta Duarte
> >> Especialista em Redes de Computadores
> >> Linux User #195299
> >> Ribeirão Preto - SP
>
> Ulalá!!! :P
>
> Não é sempre que ganhamos um elogio destes do mestre :D
>
> Desculpem-me pela demora em responder... uma virose me derrubou
>
> Grande Júlio, coloque o exemplo no livro sim!
>
> Senhores, a explicação:
>
> Por questões de didática, vamos começar com um caso mais simples em
> que não há espaços em branco.
>
> Vamos assumir que a linha original seja:
>
> Model=Samsung0411N, Serial=00000005464, blablabla=asdadqddq
>
> #carregar a linha em uma variável
> linha=$(<arquivo);
> #utilizando a vírgula como delimitador, vamos pegar o primeiro campo
> como se fosse o resultado de um cut -d, -f1
> echo ${linha%%,*};
> Model=Samsung0411N
>
> Isto não é exatamente a sintaxe de um atribuição de valor a uma
> variável? Podemos nos valer disto e utilizar o eval para executar esta
> string como se fosse um comando.
> eval ${linha%%,*};
>
> Agora, temos uma variável Model com o conteúdo desejado :D
> echo $Model
> Samsung0411N
>
> Agora, como a solicitação da thread envolvia um caracter de espaço,
> que provocaria erro no eval, tivemos que substituir os espaços por um
> caracter qualquer que não atrapalhasse.
> linha=${linha// /_}
>
> E, no final, precisamos devolver o espaço ao seu devido lugar
> echo ${Model//_/ }
>
> Claro?
>
>
> --
> Fabiano Caixeta Duarte
> Especialista em Redes de Computadores
> Linux User #195299
> Ribeirão Preto - SP
>  
>


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



reply via email to

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