Advertisement
  1. Computer Skills
  2. Terminal

Grep e sed Desmistificados

Scroll to top
Read Time: 10 min

() translation by (you can also view the original English article)

Grep. Você ouve muito isso. Você vê aqueles caras crípticos de T.I. digitando o comando, administradores de sistema mencionando isso quando passam, você até vê isso em alguns scripts shell. Parece uma daquelas coisas que simplesmente existem, mas não são para você. Esse artigo vai mudar isso - vamos explicar e dar uma olhada rápida no grep (e seu amigo menos famoso sed) nessa nova parte de OSX Desmistificado.


Introdução

Grep

Grep é um utilitário de linha de comando para buscar e filtrar algum tipo de input textual baseado em parâmetros que você passa.

Grep é um utilitário de linha de comando para buscar e filtrar algum tipo de input textual baseado em parâmetros que você passa. Em outras palavras, ele roda no Terminal (Aplicativos → Utilitários → Terminal), e é usado exclusivamente por digitação de comandos. Existem, é claro, interfaces gráficas que ajudam um pouco, mas nenhuma é tão poderosa ou versátil como a simples utilização da linha de comando, então é nisso que iremos focar.

Isso tudo é legal, mas o que isso realmente faz? O trecho acima soa muito vago? Aqui está um exemplo. Digamos que você tem um bloco de texto em um arquivo chamado jungle.txt com cinco linhas:

1
A lion sleeps in the jungle
2
A lion sleeps tonight
3
A tiger awakens in the swamp
4
The parrot observes
5
Wimoweh, wimoweh, wimoweh, wimoweh

Para encontrar a linha que contém a palavra tigre, usamos o grep assim:

1
grep tiger jungle.txt

O resultado que nos é dado é:

1
"A tiger awakens in the swamp"

Ok, isso está claro, certo? Vamos dar um passo para trás porém.

Atualizando o Grep

Acontece que o grep do Mac é mais lento que o grep GNU, então vamos fazer uma atualização primeiro. Para instalar um grep mais rápido, digite o seguinte no Terminal e aperte enter:

1
brew install https://raw.github.com/Homebrew/homebrew-dupes/master/grep.rb

Por favor note que você precisa do Homebrew instalado para poder fazer isso, e para descobrir como instalar o Homebrew, veja meu artigo anterior.

Um grande número de utilitários vai constantemente depender do grep para buscar dados de grandes arquivos de texto ou websites capturados.

O que conseguimos fazendo essa atualização? Bem, muitos aplicativos usam a aplicação instalada nativa do grep para funcionar. Por exemplo, um grande número de utilitários vai constantemente depender do grep para buscar dados de grandes arquivos de texto ou websites capturados. Portanto, todos os seus utilitários que usam grep vão agora ser muitas vezes mais rápidos nas suas partes que usam grep. Adicionalmente, você pode algumas vezes precisar usar o grep em algum tipo de log de erro (vamos dizer que você tem um log de erro enorme de uma aplicação e o serviço de suporte do app fala para você colar para ele o "grep port-1723"). Se o log tiver milhões de linhas de código, você pode economizar muito tempo usando esse grep muito mais rápido.

Uma vez que o Homebrew instalar seu novo grep, tente fazer o seguinte se você fez os arquivos. Se não, vá em frente e faça-os, então rode o comando e tenha certeza que tudo funciona.

1
grep tiger jungle.txt

Sed

Sed é um stream editor. Falando de forma crua, ele pega um input, o edita, e devolve o conteúdo editado. Esteja essa edição acontecendo em um arquivo ou o texto sendo fornecido diretamente do Terminal é completamente irrelevante para o sed - ele tem uma altamente avançada e configurável função, e a faz na melhor de sua habilidade.

Sed pega algum input de texto, um comando de como mudá-lo, e produz o resultado alterado.

Então onde o sed é usado? Editando conteúdos de arquivos e coisas do tipo, é claro, mas acontece que ele funciona perfeitamente junto com o grep. Porém, vamos ver alguns exemplos de puro sed antes. Digite o seguinte no Terminal:

1
echo "Hello"

e aperte enter. O terminal diz hello. Agora digite

1
echo "Hello" | sed 's/Hell/Heaven/'

e aperte enter. Você deve ver "Heaveno". O que aconteceu? Vê, o sed trabalha com dois argumentos. O primeiro é o que é passado para ele, o input, e o segundo é a string (você pode ver que é uma string por que está entre aspas) que diz a ele que ações realizar no primeiro argumento. No nosso caso isso é:

  • s (substituir)
  • / (delimitador - no nosso caso barra inclinada para frente, veja o próximo parágrafo para alternativas)
  • Hell (padrão de expressão regular para buscar)
  • Heaven (string para substituição)

A segunda lista menciona alternativas para a barra inclinada para a frente como delimitadora; algumas vezes elas são muito úteis por ter que, por exemplo, escrever URLs ou caminhos de arquivos. Tome por exemplo a url myfolder/mysubfolder/myfile. Se colocarmos isso no sed para substituir por myotherfolder/myotherfile, o parâmetro vai parecer-se com: s/myfolder/mysubfolder/myfile/myotherfolder/myotherfile/ o que é um grande saco de coisa sem sentido - sed não pode saber qual desses fragmentos é uma expressão regular e qual é a string para substituição. Portanto, precisaríamos escapar as barras inclinadas para frente no nosso caminho do arquivo com uma barra inclinada para trás, então cada barra inclinada para frente no caminho se tornaria \/. Imagino que você possa ver o problema. O novo parâmetro do sed fica assim:

1
sed 's/myfolder\/mysubfolder\/myfile/myotherfolder\/myotherfile/'

Esse escassamente legível formato é chamado de uma "cerca de estacas", e para evitá-lo, sed dá suporte a diferentes delimitadores como underscore (_), dois pontos (:) e pipe (|). Por exemplo, se quisermos usar o caractere pipe como o delimitador, ficaríamos com o seguinte:

1
sed 's|myfolder/mysubfolder/myfile|myotherfolder/myotherfile|'

Muito melhor, não?

Uma outra coisa, porém. Dissemos que o sed leva dois argumentos, mas somente passamos para ele um - depois do comando sed. Isso por causa do caractere pipe depois do nosso comando echo. O pipe serve como um meio para direcionar o resultado do operador da esquerda para o input do operador da direita. No nosso caso, o caractere pipe disse ao programa sed "Tome como input o que quer que seja que você receba de o que quer que seja que estiver no meu lado esquerdo". sed não faz idea que está lidando com echo - ele não precisa saber. Tudo que ele sabe é que está recebendo um input de texto. Discutir o pipeline em mais detalhes que isso está fora do escopo desse artigo, mas sinta-se livre para ler sobre se você estiver interessado.

O pipe serve como um meio para direcionar o output do operador da esquerda para o input do operador da direita.

Então como combinamos isso com o grep? É exatamente a mesma coisa. Pegando nosso exemplo anterior, vamos colocar o seguinte no terminal.

1
grep tiger jungle.txt | sed 's/swamp/desert/'

e temos o output

1
"A tiger awakens in the desert"

Agora vamos ver um caso de uso no mundo real.


Aplicação no Mundo Real

Para nossa "dissecação" vamos pegar o comando grep+sed de um utilitário popular de clima e explicá-lo passo a passo. Vá em frente e baixe o utilitário de exemplo. Uma vez baixado, abra-o em um editor de texto de qualquer tipo. Você irá notar que não é mais do que um arquivo XML. Se você não tem experiência com XML, não se preocupe. Josh já escreveu um surpreendente artigo sobre Geektool e seus pormenores. Não iremos lidar com os detalhes disso tudo hoje. Ao contrário, vamos focar na parte entre as tags <string>:

1
 curl --silent "http://xml.weather.yahoo.com/forecastrss?w=28348727&u=c" | grep -E '(Current Conditions:|C<BR)' | sed -e 's/Current Conditions://' -e 's/<br \/>//' -e 's/<b>//' -e 's/<\/b>//' -e 's/<BR \/>//' -e 's///' -e 's/<\/description>//'

Essa bagunça críptica é um simples comando de Terminal - nada mais. Você pode até colar isso no Terminal e você vai ver a condição climática para a cidade de Makati nas Filipinas, que o autor original estabeleceu para buscar. O utilitário fala ao Geektool para rodar tal comando e pegar qualquer output que receber ao rodá-lo. Vamos dar uma olhada nisso, segmento de pipe por segmento de pipe, e explicar em detalhe:

1
curl --silent "http://xml.weather.yahoo.com/forecastrss?w=28348727&u=c"

curl é uma ferramenta para transferir dados com uma sintaxe de URL. Isso significa que ele pode ir a uma URL e buscar dados dela.

Curl é uma ferramenta para transferir dados com uma sintaxe de URL na linha de comando.

Se você colar a URL citada no seu browser (ou simplesmente clicar aqui), você vai notar que você recebe um arquivo XML do Yahoo! - eles têm um serviço de condições climáticas no ar que você pode facilmente acessar e buscar data dele. Isso é exatamente a mesma coisa que você recebe quando faz um curl dele; só que ao invés do browser, o input é enviado para o Terminal. A flag --silent diz ao curl para se silenciar sobre o progresso, status e erros, para que o único output que tenhamos seja o output que precisamos (ou nada, se falhar).

1
grep -E '(Current Conditions:|C<BR)'

O caractere pipe segue, significando que o output do curl é enviado ao grep como input. Grep recebe esse arquivo XML baixado no formato texto, e roda uma busca nele com a flag -E, que significa Extended Regular Expression. O valor está buscando pela string Current Conditions: ou C<BR (o caractere pipe dentro de uma expressão regular significa “ou”). Para esclarecimento adicional, se você tivesse digita o seguinte no nosso exemplo anterior.

1
grep -E '(tiger|weh)' jungle.txt

você teria

1
A tiger awakens in the swamp
2
Wimoweh, wimoweh, wimoweh, wimoweh

Porque ele retorna todas as linhas que contêm ou “tigre” ou “weh”.

Então se rodarmos esses dois primeiros segmentos pipe juntos assim:

1
curl --silent "http://xml.weather.yahoo.com/forecastrss?w=28348727&u=c" | grep -E '(Current Conditions:|C<BR)'

teremos o seguinte:

1
<b>Current Conditions:</b><br />
2
Haze, 23 C<BR />

Mas nós queremos o “Haze, 23 C”. Aqui que o sed entra. Simplesmente substituímos qualquer coisa que não queremos por uma string vazia (nada) efetivamente deletando isso.

1
sed -e 's/Current Conditions://' -e 's/<br \/>//' -e 's/<b>//' -e 's/<\/b>//' -e 's/<BR \/>//' -e 's///' -e 's/<\/description>//'

A flag -e é uma abreviação de --expression= e nos permite encadear múltiplos comandos sed. Portanto, primeiro substituímos a string “Condições Correntes:” por nada, seguindo substituindo <br /> por nada, etc. até que cheguemos ao possível fim da linha (<description>).

No final, tudo o que sobrou é “Haze, 23 C”.

Devo mencionar que o utilitário que usamos como exemplo poderia ter sido feito bem melhor, mas a pura complexidade do comando usado pareceu uma oportunidade muito boa de cobrir múltiplos exemplos de uma vez. O autor poderia ter, por exemplo, simplesmente buscado a linha contendo “Current conditions:” e a linha depois dessa com a combinação de flags -A 1, sem basear-se no símbolo de temperatura (nesse caso, baseamo-nos no Celsius, mas e se quiséssemos Fahrenheit? A busca grep por C<br do autor falharia). De qualquer maneira, o exemplo serviu um propósito - e ele foi introduzir para você o maravilhoso mundo do grep e sed.


Mais Recursos

Enquanto ensinar expressões regulares avançadas e mais profundamente as funcionalidades do grep, curl e sed está fora do escopo desse artigo (e desse site), fique à vontade para ver os recursos seguintes se você quiser saber mais.


Conclusão

Agora você sabe o básico de grep, sed e até curl. Enquanto esse curso introdutório está longe de ser o suficiente para torná-lo um especialista, esperamos que foi pelo menos o suficiente para deixá-lo interessado em tentar sua própria colheita e busca de dados. Pelo menos, é algo sobre o que se conversar perto do refrigerador de água na Segunda-feira.

Espero que tenha gostado, e se você está querendo um desafio, tente reescrever o utilitário para não somente ser agnóstico quanto ao símbolo de temperatura, mas também descobrir a localização do usuário sozinho, sem ter que alterar manualmente o parâmetro 'w' na URL do Yahoo!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Computer Skills tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.