A história do “grep”

A história do 'grep'

O grep é uma das ferramentas mais tradicionais para uso na linha de comandos de sistemas operacionais unix-like (parecidos com o UNIX), inclusive no GNU/Linux, e a sua função mais básica é buscar por padrões de texto em um ou mais arquivos e exibir as correspondências encontradas no terminal. Contudo, apesar de estar por aí desde o início dos anos 70, pouca gente sabe da interessante história por detrás de seu nome, e é sobre isso que eu pretendo falar.

Este artigo se baseia no relato de Brian Kernighan neste vídeo.

Nos primeiros anos dos sistemas Unix, o poder de processamento dos computadores era extremamente limitado. No início dos anos 1970, o PDP-11/20, da Digital, máquina que rodou a primeira versão oficial do Unix, não costumava ter mais do que 32 ou 64 quilobytes de memória e trabalhava com unidades de armazenamento com capacidade na ordem dos 5 megabytes. Com base nisso, nós podemos imaginar como arquivos e programas eram dimensionados para ocupar o mínimo posśivel de espaço e recursos.

Digital PDP11-IMG 1498 cropped

A filosofia UNIX

Contudo, embora a carência de recursos fosse um fator importante para que os programas fossem desenvolvidos visando a simplicidade e a objetividade, essas preocupações também faziam parte de uma cultura de desenvolvimento defendida por programadores como Ken Thompson e Dennis Ritchie, a filosofia UNIX, cuja definição mais citada é aquela dada por Douglas McIlroy, criador do encadeamento de comandos por pipe:

Esta é a filosofia UNIX:

  • Escreva programas que façam apenas uma coisa, mas que a façam bem feita.
  • Escreva programas que trabalhem juntos.
  • Escreva programas que manipulem fluxos de texto, pois esta é uma interface universal."

Teletipos

Outra característica dos primeiros anos do Unix era o uso comum de máquinas de teletipo (os terminais TTY vistos na foto abaixo) como terminais, ou seja, toda troca de informações entre o sistema operacional e o utilizador era feita por linhas de texto impressas nas folhas de papel de um formulário contínuo.

Ken Thompson (sitting) and Dennis Ritchie at PDP-11 (2876612463)

Sendo assim, além das limitações já mencionadas, todas as interfaces estavam fisicamente restritas ao que podia ser feito em uma linha de texto por vez -- afinal, depois de impressa uma linha, não havia como voltar e "desimprimi-la". Foi nesse contexto que surgiram diversas ferramentas atreladas ao paradigma das linhas, entre elas, os editores de texto orientados a linhas (ou apenas "editores de linhas"), como o QED e, posteriormente, o ed.

O editor 'ed'

Desenvolvido originalmente por Ken Thompson, a partir de outro editor de linhas bastante utilizado nos anos 1960, o QED, o ed tornou-se o editor de textos padrão do sistema operacional Unix e ainda hoje faz parte dos padrões POSIX para sistemas operacionais unix-like.

De fato, o ed (versão GNU) estava presente no sistema base de todas as distribuições que eu utilizei no passado, mas, enquanto escrevia este artigo, descobri que ele não estava presente na minha instalação do Debian Sid, o que me obrigou a instalá-lo para criar os exemplos deste artigo.

Diferente de todos os editores de texto que conhecemos hoje, os editores de linha, como o ed, eram projetados para oferecer respostas visuais apenas sob demanda, o que faz sentido se nos lembrarmos de que toda resposta visual teria que ser impressa em papel.

Abrindo um arquivo

Não caberia transformar este artigo em um tutorial sobre o ed, mas vale a pena observar como algumas das suas características de operação influenciram outras ferramentas da linha de comandos.

:~$ ed autopsicografia.txt
352

Quando iniciada, a versão GNU do editor não exibe nada além da quantidade de caracteres do arquivo (352) e entra no modo de espera de comandos. Isso nos mostra que o ed também pode ser classificado como um precursor dos editores de textos "modais" posteriores, como o ex (EXtended) e o vi (VIsual).

Para ilustrar essa característica, o modo de inserção de linhas é ativado com o comando a (append), do qual sairíamos com um comando de interrupção (como o Ctrl+C, por exemplo).

No ed, os comandos são representados por um único caractere, como:

  • p - (print) exibir
  • d - (delete) apagar
  • s - (substitute) substituir
  • q - (quit) sair

Em conjunto com esses comandos, nós também podemos especificar sobre quais linhas eles devem atuar:

3,7p - imprimir as linhas de 3 a 7
1d   - deletar a primeira linha
$d   - deletar a última linha

Esse estilo de comandos é muito conhecido por quem está familiarizado com o utilitário sed (Stream EDitor).

No exemplo abaixo, nós especificamos que queremos imprimir todas as linhas na faixa entre a linha 1 e a última linha ($) do arquivo que abrimos no exemplo anterior.

1,$p
Autopsicografia

O poeta é um fingidor
Finge tão completamente
Que chega a fingir que é dor
A dor que deveras sente.

E os que lêem o que escreve,
Na dor lida sentem bem,
Não as duas que ele teve,
Mas só a que eles não têm.

E assim nas calhas de roda
Gira, a entreter a razão,
Esse comboio de corda
Que se chama coração.

(Fernando Pessoa)

Buscando linhas por expressões regulares

Nós também podemos encontrar a ocorrência de um padrão de texto a partir da linha seguinte daquela em que estivermos trabalhando. A forma de especificar esse padrão é através de uma expressão regular e o comando é escrito entre barras (/regex/), como podemos ver abaixo:

:~$ ed autopsicografia.txt
352
4
Finge tão completamente
/dor/p
Que chega a fingir que é dor
9p
Na dor lida sentem bem,
/eles/
Mas só a que eles não têm.

Observe que o comando p, ao menos na versão moderna do ed, é opcional e é presumido por padrão.

Se quisermos encontrar a ocorrência do padrão em todas as linhas do arquivo, ou seja, se quisermos fazer uma busca global, nós utilizamos o comando g:

g/[Ff]ing[ei]/p
O poeta é um fingidor
Finge tão completamente
Que chega a fingir que é dor

E é aqui que começamos a entender a relação entre o editor ed e o utilitário grep!

Do g/re/p ao grep

Embora o editor ed permitisse localizar globalmente todas as linhas que casassem com um dado padrão com a sintaxe g/Regular Expression/p, ou g/re/p, os limitados recursos computacionais da época inviabilizavam que grandes arquivos de texto fossem abertos para que essas buscas fossem executadas.

Diante desse problema, Ken Thompson (ele, mais uma vez), desenvolveu rapidamente um programa dedicado exclusivamente à tarefa de localizar e imprimir linhas de um ou mais arquivos conforme um padrão de texto especificado, fazendo exatamente o que o comando g/re/p faria no editor ed, mas sem a necessidade de carregar arquivos inteiros na memória, e assim nasceu o utilitário que ele chamou de grep.

Uma última observação

Quando desenvolveu sua versão do editor QED para o CTSS (Compatible Time Sharing System), Ken Thompson introduziu a funcionalidade das expressões regulares, herdada posteriormente por outros programas do sistema Unix, como ed, sed, grep e interpretadores como o perl e o awk.

Músico, programador, designer e apaixonado pelos ideais do Software Livre.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Post comment