|
From: | Julio C. Neves |
Subject: | Re: [shell-script] especie de "if-then-else" com sed |
Date: | Wed, 1 Oct 2014 18:34:47 -0300 |
Lá no início deste capítulo, dissemos que o sed, por ser uma linguagem de programação completa, possui comandos para controle e desvio de fluxo. Vamos ver como fazer isso.
Muitas vezes somos obrigados a criar um desvio (em inglês branch) que ocorrerá dependendo de uma condição e outras vezes precisamos de um desvio incondicional, em que o fluxo do programa é sempre desviado.
O primeiro que citamos, o condicional, é chamado pelo comando t e desviará para um ponto do sed caso a última substituição (s/.../.../) tenha sido bem executada;
O segundo, o incondicional, é chamado pelo comando b e sempre desviará para um outro ponto do script.
Para mudar o fluxo de execução do sed, você precisa especificar o endereço para o qual haverá o desvio e rotular esse local. Caso este rótulo não tenha sido definido, o desvio se dará para o final do script. Para criar um rótulo, basta preceder com um dois pontos (:) o nome que você escolheu e colocá-lo no endereço para o qual você deseja que o programa vá.
...
:ROTULO
...
Veja esse exemplo, onde desejamos trocar todas as letras minúsculas que ocorram antes de um hífen (-) por um algarismo 0.
$ sed -r '{
> :volta
> s/^([^-]*)[a-z]/\10/
> t volta
> }' <<< abc9Aaa-a111a
0009A00-a111a
A primeira linha do script é o rótulo :volta, a segunda linha troca (s) a partir do início (^), tudo que não é hífen (([^⁻]*)) e tenha uma letra minúscula ([a-z]) após. Isso será trocado pelo valor do retrovisor (\1) cujo texto foi gerado pelo grupo definido pelos parênteses, seguido por um zero. O comando t da terceira linha, diz para o fluxo voltar para o rótulo :volta caso a substituição tenha sido bem sucedida, pois isto é sinal que ainda pode haver mais letra(s) para ser(em) substituída(s). Como houve um retorno, o sed não será completado enquanto estiver achando letras e por isso não lerá outro registro, isto é, formamos um loop para cada linha lida que tenha letra(s) antes do um hífen (-). Caso a linha não tenha hífen (-), todas as letras serão trocadas por zeros.
Uma coisa interessante é que nesse caso, a execução será feita de traz para a frente e, para você ver todos os passos do loop sobre a mesma linha, vamos inserir o comando P. Veja:
$ sed -r '{
> :volta
> P
> s/^([^-]*)[a-z]/\10/
> t volta
> }' <<< abc9Aaa-a111a
abc9Aaa-a111a
abc9Aa0-a111a
abc9A00-a111a
ab09A00-a111a
a009A00-a111a
0009A00-a111a
0009A00-a111a
No exemplo a seguir, tirado de http://www.grymoire.com/Unix/Sed.html#uh-58 (Valew!), veremos alguns desvios incondicionais, que acarretam mudanças no fluxo de execução do script.
Ele serve listar todos os parágrafos que contenham uma determinada cadeia que estão em um arquivo especificado. Para isso partimos dos seguintes pressupostos:
Os parágrafos são separados entre si por linhas vazias (em branco);
O arquivo a ser examinado e a cadeia e ser pesquisada, serão passados como parâmetro para o programa nesta ordem.
Para facilitar a explicação, cada linha do código será numerada (cat -n). Veja:
$ cat -n testa_branch.sh
1 #!/bin/sh
2 sed -n "
3 # Se linha vazia, vá pesquisar cadeia
4 /^$/ b PesqCad
5 # Senão, acrescenta a linha ao hold buffer
6 H
7 # Fim de arquivo também é fim de parágrafo
8 $ b PesqCad
9 # Vai para o fim para saltar PesqCad
10 b
11 # Aqui que vamos procurar a cadeia no parágrafo
12 :PesqCad
13 # Manda todo o parágrafo para o pattern space
14 x
15 # Procura a cadeia, se achar imprime
16 /$1/ p
17 " $2
Linha |
Para fazer... |
4 |
/^$/ pesquisa linha vazia e quando a acha, vai para (b) PesqCad para pesquisar a cadeia no arquivo |
6 |
Se não foi para PesqCad, acrescenta esta linha ao Hold Space (H) para ir montando o parágrafo nele |
8 |
Caso encontre o fim ($), do arquivo, que também é fim de parágrafo, vai para (b) a rotina PesqCad |
10 |
Como a seguir vem a rotina PesqCad, esse desvio (b) vai para o fim do sed (porque está sem rótulo) |
12 |
Rótulo da rotina |
14 |
Manda o conteúdo do Hold Space para o Pattern Space (x) para ali poder trabalhar este parágrafo |
16 |
Pesquisa a cadeia passada como parâmetro (/$1/) e, caso exista, imprime todo o conteúdo do buffer |
17 |
Arquivo |
Olá, gente.
O título comunica mas não explica.
Estou tentando fazer um script para identificar o tipo de autenticação
das redes wifi de onde estou a partir da saída do iwlist scan.
De forma resumida, há duas linhas nessa saída que me dizem isso:
- se houver uma linha "Encryption key:off", a rede está aberta;
- caso contrário, se houver também uma linha "WPA Version 1", a
autenticação é WPA;
- caso contrário, a autenticação é WEP.
O que fiz até o momento foi
iwlist wlan0 scan | \
grep -Eo '(ESSID:".+"|Quality=[0-9]{,2}/[0-9]{2}|Encryption
key:(on|off)|WPA Version (1|2))' | \
...
Passo essa saída ainda por um sed para, ao final, converter o
resultado de colunas para linhas com awk.
A questão é que como a linha "WPA Version" pode ou não existir, isso
está quebrando meu script.
Eis que pensei em fazer uma lógica e tentar colocar um placeholder
para identificar o tipo de autenticação. Mas aí já não consegui
resolver sozinho e vim recorrer a vós. :-)
Agradeço por qualquer ajuda.
Atenciosamente.
--
MARCELO F ANDRADE | Belem, Amazonia, Brazil | http://about.me/mfandrade
[Prev in Thread] Current Thread [Next in Thread]
- especie de "if-then-else" com sed, Marcelo F Andrade, 2014/10/01
- Re: [shell-script] especie de "if-then-else" com sed, Tiago Peczenyj, 2014/10/01
- Re: [shell-script] especie de "if-then-else" com sed, Ronaldo Ferreira de Lima, 2014/10/01
- Re: [shell-script] especie de "if-then-else" com sed, Marcelo F Andrade, 2014/10/02
- Re: [shell-script] especie de "if-then-else" com sed, Julio C. Neves, 2014/10/02
- Re: [shell-script] especie de "if-then-else" com sed, Ronaldo Ferreira de Lima, 2014/10/02
- Re: [shell-script] especie de "if-then-else" com sed, Julio C. Neves <=
- Re: especie de "if-then-else" com sed, itamarnet, 2014/10/02
- Re: especie de "if-then-else" com sed, itamarnet, 2014/10/02
- Re: [shell-script] Re: especie de "if-then-else" com sed, Marcelo F Andrade, 2014/10/02
- Re: [shell-script] especie de "if-then-else" com sed, Paulo Bettega, 2014/10/02
- Re: [shell-script] especie de "if-then-else" com sed, Paulo Bettega, 2014/10/04
- Prev by Date: Re: [shell-script] especie de "if-then-else" com sed
- Next by Date: Re: especie de "if-then-else" com sed
- Previous by thread: Re: [shell-script] especie de "if-then-else" com sed
- Next by thread: Re: especie de "if-then-else" com sed
- Index(es):