Trabalhando com coringas, filtros e expressões regulares no shell

Nesse artigo mostrarei o uso de coringas, filtros e expressões regulares. Nele serão abordados tópicos como o uso de comandos trabalhando com coringas, os comandos cut, grep, head, tail, sort, tr, wc, nl, uniq e paste, que trabalham como filtro de dados e o uso de expressões regulares utilizando os comandos sed e grep.

[ Hits: 140.630 ]

Por: Cristian Alexandre Castaldi em 21/08/2004


Expressões regulares



O sed é usado como um comando editor de fluxo, utilizaremos para substituir um padrão por outro e para extrair faixas de linhas de um arquivo. As opções mais usadas são:
  • -e Adiciona comandos no script que serão usados no comando que está rodando, enquanto está processando a entrada.
  • -f Adiciona comandos contidos em um arquivo que serão usados no comando que está rodando, enquanto está processando a entrada.

Endereçamento:
Endereços no sed localizam as linhas no texto que os comandos são aplicados. Estes endereços podem ser:
  • O número de uma linha;
  • O número de uma linha com um intervalo. A forma é n~s, onde n é a linha inicial e s a final;
  • O símbolo $ indicando a próxima linha da próxima entrada do arquivo;
  • Uma expressão regular delimitada por barras (/regex/).

As opções mais usadas são:
  • s Substitui um padrão por outro.
  • g Substitui todas as ocorrências globalmente.
  • n Substitui um número determinado de ocorrências.
  • d Delete

Vamos analisar o arquivo /etc/protocols:

$ more /etc/protocols

# /etc/protocols:
# $Id: protocols,v 1.1 1995/02/24 01:09:41 imurdock Exp $
#
# Internet (IP) protocols
#
#       from: @(#)protocols     5.1 (Berkeley) 4/17/89
#
# Updated for NetBSD based on RFC 1340, Assigned Numbers (July 1992).


ip         0       IP         # internet protocol, pseudo protocol number
icmp       1       ICMP       # internet control message protocol
igmp       2       IGMP       # Internet Group Managemento

Suponha que não quero que apareçam mais os comentários "#":

$ sed '/^#/d' /etc/protocols
ip         0       IP         # internet protocol, pseudo protocol number
icmp       1       ICMP       # internet control message protocol
igmp       2       IGMP       # Internet Group Management

Observe que todas as linhas que se iniciavam com # foram deletadas.

Agora vamos substituir um padrão por outro, a sintaxe é bem simples s/padrão velho/padrão novo/. Observe o arquivo nomes.txt, vamos mudar o nome Amaral para Julia:

$ cat nomes.txt
Amaral
Suzan
Mariana
Wilson
Yan

$ sed -e 's/Amaral/Julia/' nomes.txt
Julia
Suzan
Mariana
Wilson
Yan

Imagine que se houvesse mais de uma ocorrência do nome Amaral poderíamos usar o parâmetro g para mudar todas elas. Então o comando ficaria assim:

$ sed -e 's/Amaral/Julia/g' nomes.txt

Agora vamos mudar o nome Amaral para Julia e depois deletar o nome Wilson tudo de uma vez:

$ cat nomes.txt |sed -e 's/Amaral/Julia/;/Wilson/d'
Julia
Suzan
Mariana
Yan

Podemos também usar padrões em combinação com números, vamos deletar a primeira linha até o nome Wilson:

$ sed '1,/Wilson/d' nomes.txt
Yan

Agora vamos mudar todas as letras a para % que aparecem nas três primeiras linhas:

$ sed -e '1,3s/a/%/g' nomes.txt
Am%r%l
Suz%n
M%ri%n%
Wilson
Yan

grep


Como sabemos, no Linux, os padrões de pesquisa são chamados de expressões regulares. Para pesquisar um arquivo inteiro, isso na época dos primeiros sistemas Unix, o usuário prefixava o comando com global. E, uma vez que uma combinação era descoberta ela era listada na tela com o comando print. Para juntar toda a maçaroca de comandos, a operação indicada era global/regular expression/print. Como vemos a frase era longa e logo os usuários abreviaram para g/re/p e posteriormente acabou se tornando grep.

Existe uma quantidade enorme de opções que podemos usar, entre elas destacam-se:
  • ^ Indica tudo que estiver no início.
  • $ Indica tudo que estiver no fim.

Vamos listar somente os diretórios do /etc:

$ ls -l /etc | grep '^d'
drwxr-xr-x    3 root     root         1024 May 31 09:38 CORBA
drwxr-xr-x   19 root     root         1024 May 31 10:13 X11
drwxr-xr-x    2 root     root         2048 May 31 13:31 alternatives
drwxr-xr-x    2 root     root         1024 May 31 10:00 apache
Agora quero saber quantos arquivos .conf existem dentro do diretório /etc:

$ ls -R /etc | grep -c '.conf$'
107

Observe que ele achou 107 arquivos no diretório /etc. Vamos supor que eu preciso saber somente quais são os nomes existentes no arquivo nomes.txt que começam com M, S e W.

$ grep [MSW] nomes.txt
Suzan
Mariana
Wilson

Nós podemos também pesquisar por faixa [0-9][a-zA-Z], observe:

$ grep [A-S] nomes.txt
Amaral
Suzan
Mariana

Agora vamos pesquisar todos os números de 1 a 3 dígitos iniciados por 1 no arquivo numeros.txt:

$ cat numeros.txt
102
32
1800
900
132
5600
33
9015
12
1486

$ cat numeros.txt | grep '\<[0-9]\{1,3\}\>' | grep '^1'
102
132
12
  • [0-9] - Indica a faixa de caracteres que será pesquisada, ou seja, de 0 a 9.
  • {1,3} - Indica a quantidade de dígitos que os números devem ter na pesquisa, ou seja, de 1 a 3 dígitos.
  • ^1 - Indica somente os números iniciados com 1.

Como podemos observar, o grep possui uma infinidade de opções para se obter o resultado desejado. Espero que com estes exemplos possa ter ajudado a comunidade Linux.

Página anterior     Próxima página

Páginas do artigo
   1. Introdução
   2. Coringas
   3. Filtros
   4. Expressões regulares
   5. Bibliografia
Outros artigos deste autor

Trabalhando com shell e variáveis de ambiente

Lynis: Sistema de auditoria e segurança para Linux

Criando, monitorando e terminando processos

Usando partições e sistemas de arquivos

Gerenciando quotas de disco

Leitura recomendada

Atualizando versões do openSUSE pela internet

Pós-instalação do Arch Linux em um Dell Vostro 1400

Migrando para Linux sem medo

Como criar pacotes para o Arch Linux

Guia: Pós-instalação do Debian Linux 4.0 Etch/Stable

  
Comentários
[1] Comentário enviado por daaugusto em 21/08/2004 - 15:04h

O certo seria "curinga" (do jogo de cartas) e não "coringa".

[2] Comentário enviado por pop_lamen em 21/08/2004 - 15:30h

Cara seguinte...
tenho um saida mais ou menos assim...:
blah blah blah [blah blah] (blah blah)
e quero separar somente o que esta dentro dos colchetes...
como faco!?

[3] Comentário enviado por fabio em 21/08/2004 - 20:15h

Vixe.. Pessoal, o autor colocou curinga no artigo inteiro, eu que em minha santa ignorância mudei tudo para coringa. Assim que voltar de viagem (Domingo) mudo isso.

[]'s

[4] Comentário enviado por fabio em 21/08/2004 - 20:19h

Aproveitando o embalo, veja se isso funciona:

echo 'blah blah blah [esse blah blah aqui] (blah blah)' | sed 's/^.*\[\(.*\)\].*$/\1/'

[]'s

[5] Comentário enviado por pereira.celso em 22/08/2004 - 13:56h

kra muito bom artigo....parabéns!

valeu

[6] Comentário enviado por pop_lamen em 22/08/2004 - 18:34h

Cara funcionar funcionou
soh q eu ainda nao peguei as manhas desse SED

[7] Comentário enviado por crildo em 23/08/2004 - 09:05h

Leia a man page do comando ou consulte o arquivo pdf LPI Linux Certification In a Nutshell. Galera obrigado pelos comentários e críticas, até mais...

[8] Comentário enviado por wronieri em 23/08/2004 - 14:24h

crildo muito bom seu artigo parabéns :-)

[9] Comentário enviado por flipe em 23/08/2004 - 17:22h

no grep seria bom a opção -e

[10] Comentário enviado por agk em 25/08/2004 - 09:54h

Excelente artigo, continue assim amigo, gostei muito. Já estava fazendo algumas coisas em Shell faz algum tempo, mas com esse artigo vejo que as possibilidades são muitas, alias tenho uma dúvida, o que não dá pra fazer em shell? ehehe...

[11] Comentário enviado por shadowm00n em 30/10/2006 - 16:56h

no trecho abaixo, como eu faria para passar variáveis como parametro, exemplo: ao inves de passar .../a/%/... eu quero passar .../$var1/$var2/...

$ sed -e '1,3s/a/%/g' nomes.txt
Am%r%l
Suz%n
M%ri%n%
Wilson
Yan

[12] Comentário enviado por leodamasceno em 13/10/2009 - 08:49h

Cara, parabéns!
Ótimo artigo. Estou estudando pra LPI, e nessa questão dos "coringas" você fez uma ótima explicação.
Mais uma vez, parabéns.

[13] Comentário enviado por rnduart em 22/04/2011 - 14:06h

Difícil para que esta começando como eu. Mas vou estudar o artigo mais vez para aprender.

[14] Comentário enviado por esaraujo em 08/05/2013 - 09:37h

Artigo muito bom.
Obrigado.

[15] Comentário enviado por pmargreff em 20/05/2015 - 23:27h


Mais de dez anos se passaram da data de escrita e este artigo continua sendo relevante, parabéns, muito no mesmo.


Contribuir com comentário