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.631 ]

Por: Cristian Alexandre Castaldi em 21/08/2004


Filtros



cut


O comando cut é usado para extrair colunas de arquivos, como se fossem tabelas. Para especificar um intervalo deve ser usada uma vírgula entre valores separados e para especificar uma faixa deve ser usado um hífen. As opções mais usadas são:
  • -c Extrai a lista de posições em colunas
  • -d Utilizado como um delimitador junto à opção -f extrai as colunas especificadas na lista
  • -f Significa os campos especificados no arquivo.

Observe o arquivo contatos.txt, ele está dividido em nome, idade, telefone e endereço:

$ cat contatos.txt
Cristina:22 anos:8888 9999:Avenida Presidente Dutra, 12
Roberta:25 anos:5555 4444:Rua 25 de Abril, 15
Paulo:22 anos:6565 6565:Rua Mario Vicente, 110
Fabio:26 anos:7896 6954:Rua Dona Marta, 22

Suponha que apenas desejamos saber o nome das pessoas e o número do telefone:

$ cut -d: -f1,3 contatos.txt
Cristina:8888 9999
Roberta:5555 4444
Paulo:6565 6565
Fabio:7896 6954

Agora imagine que desejamos saber o nome, o telefone e o endereço:

$ cut -d: -f1,3-4 contatos.txt
Cristina:8888 9999:Avenida Presidente Dutra, 12
Roberta:5555 4444:Rua 25 de Abril, 15
Paulo:6565 6565:Rua Mario Vicente, 110
Fabio:7896 6954:Rua Dona Marta, 22

Agora quero apenas saber o nome e a idade das pessoas:

$ cut -d: -f1,2 contatos.txt
Cristina:22 anos
Roberta:25 anos
Paulo:22 anos
Fabio:26 anos

grep


O comando grep procura por textos ou expressões regulares dentro de um ou mais arquivos. Mais adiante veremos alguns exemplos com o comando grep com expressões regulares, agora veremos exemplos mais básicos. As opções mais comuns são:
  • -i Ignora a distinção entre letras maiúsculas e minúsculas.
  • -n Mostra o número de cada linha encontrada pelo grep.
  • -l Lista os nomes dos arquivos ao invés de linhas individualizadas.
  • -c Conta o número de vezes que a palavra ou caractere aparece no arquivo.
  • --help Exibe informações das opções que podem ser usadas pelo grep.

Vamos a um exemplo simples, imagine que eu gostaria de saber qual é a porta utilizada pelo serviço ssh:

$ grep ssh /etc/services
ssh      22/tcp      # SSH Remote Login Protocol
ssh      22/udp      # SSH Remote Login Protocol

Como podemos ver, o serviço ssh utiliza a porta 22. Agora eu quero saber o número das linhas onde aparece a palavra ssh:

$ grep -n ssh /etc/services
29:ssh      22/tcp         # SSH Remote Login Protocol
30:ssh      22/udp         # SSH Remote Login Protocol

A opção -n adicionou os números das linhas onde aparece a palavra ssh. Agora imagine que eu estou com um problema no meu ssh e gostaria de verificar quais são os arquivos de configuração no diretório /etc que possuem a palavra ssh:

$ grep -sl ssh /etc/*
/etc/bash_completion
/etc/passwd
/etc/passwd-
/etc/passwd.bak
/etc/screenrc
/etc/services
/etc/shadow
/etc/shadow-
/etc/shadow.bak

Estes são os arquivos que contêm informações referentes ao ssh além dos arquivos que estão contidos no diretório /etc/ssh. A opção -s esconde as mensagens de erro e a opção -l lista os arquivos que contêm a palavra ssh no diretório corrente.

head


O comando head exibe as primeiras linhas de um ou mais arquivos, o padrão é dez linhas. A opção mais usada é a -n que exibe as primeiras n linhas:

$ head -5 /etc/group
root:x:0:
daemon:x:1:
bin:x:2:
sys:x:3:
adm:x:4:

Observe que foram listadas as cinco primeiras linhas do arquivo /etc/group.

tail


O comando tail exibe as últimas linhas de um ou mais arquivos, o padrão é dez linhas. A opção mais usada é a -n que exibe as últimas n linhas:

$ tail -5 /etc/group
osdormesujo:x:104:crildo,teste,tux,win2kserver
ftp:x:1002:
teste:x:1001:
tux:x:1003:
win2kserver:x:1004:

Observe que foram listadas as últimas cinco linhas do arquivo /etc/group.

sort


O comando sort ordena as linhas dos arquivos especificados ou da entrada padrão. Existem diversas opções de classificação: ascendente, descendente, por campo do arquivo, etc. As opções mais usadas são:
  • -b Ignora espaços em brando.
  • -d Classifica na ordem do dicionário (somente letras, dígitos e espaços em branco são significativos).
  • -f Ignora a distinção entre palavras maiúsculas e minúsculas.
  • -n Classifica em ordem numérica.
  • -r Reverte a ordem de classificação.

Quero que o sort ordene os arquivos do diretório lixo:

$ ls | sort -f
basic.conf
contatos.txt
GNU.txt
ip.txt
Lista.rtf
log.txt
nomes.txt
ods1.bmp
ods2.bmp
postinfo.html
proftpd01.conf
services
servicos

Agora quero saber quais são os cinco arquivos de log que estão ocupando mais espaço em disco:

$ ls -s /var/log | sort -nr | head -5
1694 syslog
1644 daemon.log
616 wtmp
583 kern.log
565 messages

tr


O comando tr substitui ou remove os caracteres selecionados da entrada padrão para a saída padrão. As opções mais usadas são:
  • -d Remove os caracteres contidos na expressão um e mostra-os na saída padrão.
  • -s Substitui cada seqüência de caracteres repetidos na expressão dois por um único caractere.
  • --help Exibe as informações de ajuda do comando.

Observe o arquivo nomes.txt:

$ cat nomes.txt
Amaral
Suzan
Mariana
Wilson
Yan

Vamos substituir todas as letras para maiúsculas.

$ tr a-z A-Z < nomes.txt
AMARAL
SUZAN
MARIANA
WILSON
YAN

Agora vamos deletar todas as letras da saída do comando ls -l:

$ ls -l | tr -d [a-zA-Z-.]
 2625
    1                488  22 11:08
    1                178   6 10:49
    1               1810  22 10:32
    1                207  15 09:48
    1                 83   6 10:49
    1               1061  14 11:55

wc


O comando wc conta às linhas, palavras e caracteres de arquivos. As opções mais usadas são:
  • -c Mostra a contagem de caracteres.
  • -l Mostra a contagem de linhas.
  • -w Mostra a contagem de palavras.
  • -L Mostra o comprimento da linha mais longa.

Vamos analisar quantas linhas tem o arquivo /etc/group:

$ wc -l /etc/group
45 /etc/group

A saída do comando está indicando 45 linhas, eu poderia supor que existem 45 grupos cadastrados se não houver nenhuma linha em branco.

nl


O comando nl exibe os arquivos com linhas numeradas. As opções mais usadas são:
  • -w Usa número de colunas por número de linhas.
  • -s Adiciona um caractere separador.
  • -i Incrementa o número em cada linha.

$ nl -s: nomes.txt
     1:Amaral
     2:Suzan Cristina
     3:Mariana
     4:Wilson
     5:Yan

uniq


O comando uniq remove linhas desnecessárias ou duplicadas, ou seja, ele faz uma espécie de listagem de cada linha única do arquivo. As opções mais usadas são:
  • -u Lista somente as linhas que não são repetidas.
  • -d Lista somente as linhas que são repetidas.
  • -c Adiciona um contador de ocorrências de cada linha.

$ uniq -c nomes.txt
      1 Amaral
      1 Suzan
      1 Mariana
      1 Wilson
      1 Yan
      2

Observe que o comando assinalou duas ocorrências de linhas em branco no arquivo nomes.txt.

paste


O comando paste junta os arquivos na saída padrão. As opções mais usadas são:
  • -d Separa as colunas com um caractere.
  • -s Exibe cada arquivo em uma linha.

Vamos juntar o arquivo nomes.txt e idade.txt:

# paste nomes.txt idade.txt
Amaral      22 anos
Suzan       56 anos
Mariana     19 anos
Wilson      13 anos
Yan         41 anos

$ paste -d: nomes.txt idade.txt
Amaral:22 anos
Suzan:56 anos
Mariana:19 anos
Wilson:13 anos
Yan:41 anos

$ paste -s nomes.txt idade.txt
Amaral   Suzan      Mariana   Wilson     Yan
22 anos  56 anos    19 anos   13 anos    41 anos

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

Sistema de boot, níveis de execução e shutdown

Servidor CVS: Instalando, configurando e gerenciando no Linux

Criando, monitorando e terminando processos

Usando partições e sistemas de arquivos

Gerenciando quotas de disco

Leitura recomendada

Sugestões sobre distros Linux e particionamento de HD

Qual distro escolher

Instalando o Fedora Core 5 via NFS

Desmistificando o Software Livre

Instalação do Linux em pendrive com VirtualBox

  
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