Utilizando "expr" para "String Matching" através de expressões regulares em shell

Este artigo tem por intuito mostrar mais uma técnica de "String Matching" em shell tirando proveito de RegEx através do comando "expr". Este comando é encontrado na maioria dos sistemas operacionais UNIX, o que facilita o desenvolvimento em plataformas sem ferramentas GNU instaladas. No Linux, o comando faz parte do pacote "coreutils".

[ Hits: 31.526 ]

Por: Alexandre de Abreu em 16/05/2005


Introdução



O comando expr é muito conhecido pelos programadores shell (bash, ksh, sh, etc), mas a sua utilização, na maioria das vezes, restringe-se ao comando abaixo:

contador=`expr $contador + 1`

Este comando irá incrementar o valor da variável contador em 1, outras formas de alcançar o mesmo objetivo em bash seriam:

let contador++
contador=$((contador+1))
contador=$(bc <<< "$contador + 1")

É verdade que existem várias outras maneiras de fazer, mas o foco deste documento é apresentar as funcionalidades do comando "expr", um poderoso processador de expressões.

Esse comando pode ser utilizado para processar expressões matemáticas através de operadores lógicos como |, >, >=, &, que representam o OU, E, MAIOR QUE, etc, assim como também pode utilizar operadores aritméticos, como visto no exemplo acima com o operador de adição ou +, outros possíveis seriam: % ou módulo, * ou multiplicação.

Abaixo veremos exemplos de expressões aritméticas utilizando alguns operadores, assim como os parênteses para agrupar e definir a ordem de execução dos comandos:

$ expr \( 30 + 2 \) \* \( 13 % 2 \) - \( 2 \* \( 20 - 8 \) \)
8
$ expr \( 30 + 2 \) \* \( 13 % 2 \) - \( 2 \* \( 20 - 8 \) \) / 2
20
$ expr \( \( 30 + 2 \) \* \( 13 % 2 \) - \( 2 \* \( 20 - 8 \) \) \) / 2
4

    Próxima página

Páginas do artigo
   1. Introdução
   2. Utilizando expressões regulares
   3. Como validar expressões
   4. Exemplo prático
Outros artigos deste autor
Nenhum artigo encontrado.
Leitura recomendada

Monitorar servidores e enviar alertas por e-mail e SMS

Redirecionamentos, Pipes e Fluxos

Operadores de redirecionamento

Definição automática de wallpaper em função do horário

Recebendo seu IP dinâmico via email

  
Comentários
[1] Comentário enviado por fabio em 16/05/2005 - 23:27h

Belo artigo! Bom, analisando o padrão do exemplo da página 4, aí vai uma expr um pouco mais simples para se extrair o PID do processo:

expr "Apr 26 09:27:01 localhost sshd[2549]: error: Address already in use." : '.*\[\([[:digit:]]\{1,\}\)\]'

O entendimento da mesma fica como dever de casa :P

[]'s,
Fábio

[2] Comentário enviado por inode em 16/05/2005 - 23:34h

Olá Fábio,

O objetivo não é conseguir a informação de maneira mais fácil e sim de maneira mais segura e confiável. Veja que sua regex gera falso-positivos. Um exemplo:

expr "Apr 26 09:27:01 localhost sshd[2549]: error [4567]: Address already in use." : '.*\[\([[:digit:]]\{1,\}\)\]'
4567

:)

[]s

Alexandre de Abreu

[3] Comentário enviado por fabio em 17/05/2005 - 00:26h

Opa,

Mas na linha de log que você mostrou não há exemplo de duas ocorrências de par de chaves []. Uma expressão regular é construída a partir da análise de um padrão e o padrão que segui foi o citado no artigo.

Além do mais, em artigos introdutórios como o seu, devemos sempre priorizar os comandos mais simples para deixar o texto mais didático. Aposto cinco mangos contigo que 90% dos que lerem esse artigo e não forem experts em expressões regulares vão custar ou não vão entender bulúfas da página 4.

Conclusão, era mais fácil concordar que minha regex é uma alternativa resumida à sua :)

[]'s,
Fábio

[4] Comentário enviado por inode em 17/05/2005 - 01:13h

Fábio,

Abra uma sessão: Tópicos Avançaos em Shell com Expressões Regulares, coloque o artigo lá ou ainda, deixe claro que os artigos não podem ser direcionados a usuários que não sejam "experts" como você falou e assim ficamos em paz. :)

Se vamos discutir isso, que seja dito a verdade, a expressão regular para tal tarefa é a descrita no artigo, ele valida uma entrada com o padrão:

^Mes Dia HH:MM:SS Hostname software[PID] Qualquercoisa/Whatever

Escrevi o artigo no intuito de mostrar uma ferramenta e não descrever o tópico RegEx, além disso, não julgo o artigo como introdutório em lugar algum.

Valeu

Alexandre


[5] Comentário enviado por fabio em 17/05/2005 - 02:45h

Mas então, quando buscamos criar uma expressão regular, o objetivo é sempre chegar a mais simples e resumida possível. Analisando sua entrada com o padrão:

^Mes Dia HH:MM:SS Hostname software[PID] Qualquercoisa/Whatever

Podemos concluir que a informação desejada é a única que está entre colchetes. Daí o surgimento de uma expressão que busca somente as informações dentre os próprios colchetes. Não é necessário fazer a expressão "casar" com o resto do padrão se este resto não nos interessa.

Se na aula de história você vai falar sobre o homo-sapiens, não precisa falar sobre o ?homo-herectus? para o professor ou a turma entender o que é homo-sapiens. hehehe

Sua regexp está certa e completa, mas estou, através dos comentários, mostrando que nesse assunto temos diversas formas para chegarmos a um resultado final. Você respondeu como se fosse o dono da verdade, morfando o padrão da linha para uma situação imaginária só pra dizer que minha sugestão estava incorreta, mas não é por aí. Notei que sua personalidade era assim nos e-mails que me enviou antes e depois do artigo ser publicado... bom, mas isso é assunto nosso, deixa pra lá!


[]'s,
Fábio

[6] Comentário enviado por inode em 17/05/2005 - 09:59h

Cara, que comédia, eu tento mostrar algo interessante no artigo sobre expr ai vem você criticar uma simples RegEx. Que infelicidade a minha! :)

Não sou dono da verdade Fábio, mas, se é para mostrar algo, que seja mostrado da forma correta. Você tem muito que aprender ainda sobre RegEx, um dia saberá que um falso-positivo acaba com seu sistema e que o importante é segurança e confiabilidade, e não fazer a RegEx mais simples possível. Iss cabe um novo artigo, não?

Para acabar com a discussão: sua RegEx funciona! Ela retorna o último número entre colchetes, é isso que quer ler?

Bom dia! ;)

[7] Comentário enviado por lyma em 17/05/2005 - 11:48h

Gostaria de interromper esta produtiva discussão para parabenizar sobre o ótimo artigo.

Um abraço aos dois! :)

[8] Comentário enviado por inode em 17/05/2005 - 12:55h

Valeu lyma, qualquer dúvida manda ai. :)

[9] Comentário enviado por agk em 02/06/2005 - 14:51h

Bastante interessante o artigo, mas para entendê-lo melhor teria que me aprofundar um pouco mais em Shell Script como diz no final do artigo.

[10] Comentário enviado por agressiveinlinux em 18/08/2010 - 15:16h

Pessoal não sei se minha dúvida é sobre o assunto, mas lá vai, estou precisando saber qual comando uso para encontrar caracteres ascii em um texto, já tentei usar o find mais nada, o grep dá algum suporte ou vocês sabem de outro comando para fazer isso.

Obrigado!!


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts