Grep e expressões regulares para pesquisar padrões de texto no Linux

Introdução

O comando grep é um dos comandos mais úteis em um ambiente de terminal Linux. O  nome grep significa global regular expression print (impressão de expressão regular global). Isso significa que você pode usar grep para verificar se a entrada recebida corresponde a um padrão especificado. É um comando extremamente poderoso; sua capacidade de classificar entradas com base em regras complexas o torna um elo popular em muitas cadeias de comando.

Neste tutorial, você explorará as opções do comando grep e, em seguida, mergulhará no uso de expressões regulares para fazer pesquisas mais avançadas.

Pré-requisitos

Para acompanhar este guia, você precisará de acesso a um computador executando um sistema operacional baseado em Linux ou o WSL no Windows.

Uso Básico

Neste tutorial, você usará grep para pesquisar várias palavras e frases na Licença Pública geral GNU v3 e na licença BSD.

Se você estiver em um sistema Ubuntu, poderá encontrar os arquivos na pasta /usr/share/common-licenses. Copie-os para o seu diretório inicial:

				
					cd ~
cp /usr/share/common-licenses/GPL-3 .
cp /usr/share/common-licenses/BSD .
				
			

Agora que você tem os arquivos, pode começar a trabalhar com o grep.

Na forma mais básica, você usa o grep para encontrar correspondências de padrões literais em um arquivo de texto. Isso significa que se você passar uma palavra para o grep pesquisar, todas as linhas do arquivo que contém essa palavra serão impressas.

Execute o seguinte comando para o grep pesquisar cada linha que contém a palavra GNU:

				
					grep "GNU" GPL-3
				
			

O primeiro argumento, GNU, é o padrão que você está procurando, enquanto o segundo argumento, GPL-3, é o arquivo de entrada que você deseja pesquisar.

A saída resultante será cada linha contendo o texto padrão:

				
					#Output
                    GNU GENERAL PUBLIC LICENSE
  The GNU General Public License is a free, copyleft license for
the GNU General Public License is intended to guarantee your freedom to
GNU General Public License for most of our software; it applies also to
  Developers that use the GNU GPL protect your rights with two steps:
  "This License" refers to version 3 of the GNU General Public License.
  13. Use with the GNU Affero General Public License.
under version 3 of the GNU Affero General Public License into a single
...
				
			

Em alguns sistemas, o padrão pesquisado será destacado na saída em uma cor diferente.

Opções comuns

Por padrão, o grep procurará o padrão exato especificado dentro do arquivo de entrada e retornará as linhas que encontrar. Você pode tornar esse comportamento mais útil adicionando algumas flags opcionais ao grep.

Se quiser que o grep ignore a “maiúscula” do seu parâmetro de pesquisa e pesquise variações em maiúsculas e minúsculas, você pode especificar a flag -i ou --ignore-case.

Pesquise cada instância da palavra license (com maiúsculas, minúsculas ou mistas) no mesmo arquivo de antes com o seguinte comando:

				
					grep -i "license" GPL-3
				
			

Os resultados contêm: LICENSElicense, e License:

				
					#Output
                    GNU GENERAL PUBLIC LICENSE
 of this license document, but changing it is not allowed.
  The GNU General Public License is a free, copyleft license for
  The licenses for most software and other practical works are designed
the GNU General Public License is intended to guarantee your freedom to
GNU General Public License for most of our software; it applies also to
price.  Our General Public Licenses are designed to make sure that you
(1) assert copyright on the software, and (2) offer you this License
  "This License" refers to version 3 of the GNU General Public License.
  "The Program" refers to any copyrightable work licensed under this
...
				
			

Se houvesse uma instância com LiCeNsE, ela também teria sido retornada.

Se quiser encontrar todas as linhas que não contêm um padrão especificado, você pode usar a opção -v ou --invert-match.

Procure cada linha que não contenha a palavra the na licença BSD com o seguinte comando:

				
					grep -v "the" BSD
				
			

Você terá esta saída:

				
					#Output
All rights reserved.

Redistribution and use in source and binary forms, with or without
are met:
    may be used to endorse or promote products derived from this software
    without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
...
				
			

Como você não especificou a opção “ignorar maiúsculas e minúsculas”, os dois últimos itens foram retornados como sem a palavra the.

Muitas vezes é útil saber o número da linha em que as correspondências ocorrem. Você pode fazer isso usando a opção -n ou --line-number. Execute novamente o exemplo anterior com este sinalizador adicionado:

				
					grep -vn "the" BSD
				
			

Isso retornará o seguinte texto:

				
					#Output
2:All rights reserved.
3:
4:Redistribution and use in source and binary forms, with or without
6:are met:
13:   may be used to endorse or promote products derived from this software
14:   without specific prior written permission.
15:
16:THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17:ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
...
				
			

Agora você pode descobrir o número da linha se quiser fazer alterações em todas as linhas que não contêm the. Isto é especialmente útil ao trabalhar com código-fonte.

Expressões regulares

Uma “expressão regular” é uma sequência de texto que descreve um padrão de pesquisa específico.

Diferentes aplicativos e linguagens de programação implementam expressões regulares de maneira um pouco diferente. Neste tutorial você explorará apenas um pequeno subconjunto da maneira que grep descreve seus padrões.

Correspondências Literais

Nos exemplos anteriores deste tutorial, quando você pesquisou as palavras GNUthe, na verdade estava procurando expressões regulares básicas que correspondessem à sequência exata de caracteres GNUthe. Os padrões que especificam exatamente os caracteres a serem correspondidos são chamados de “literais” porque correspondem ao padrão literalmente, caracter por caracter.

É útil pensar nisso como uma correspondência de uma sequência de caracteres em vez de uma  correspondência de uma palavra. Esta se tornará uma distinção mais importante à medida que você aprende padrões mais complexos.

Todos os caracteres alfabéticos e numéricos (bem como alguns outros caracteres) são correspondidos literalmente, a menos que sejam modificados por outros mecanismos de expressão.

Âncoras

Âncoras são caracteres especiais que especificam onde na linha uma correspondência deve ocorrer para ser válida.

Por exemplo, usando âncoras, você pode especificar que deseja saber apenas sobre as linhas que correspondem à GNU logo no início da linha. Para fazer isso, você poderia usar a âncora  ^ antes da string literal.

Execute o seguinte comando para pesquisar o arquivo GPL-3 e encontrar as linhas onde GNU ocorre no início de uma linha:

				
					grep "^GNU" GPL-3
				
			

Este comando retornará as duas linhas a seguir:

				
					#Output
GNU General Public License for most of our software; it applies also to
GNU General Public License, you may choose any version ever published
				
			

Da mesma forma, você pode usar a âncora $ no final de um padrão para indicar que a correspondência só será válida se ocorrer exatamente no final de uma linha.

Este comando corresponderá a cada linha que termina com a palavra and no arquivo GPL-3:

				
					grep "and$" GPL-3
				
			

Você receberá esta saída:

				
					#Output
that there is no warranty for this free software.  For both users' and
  The precise terms and conditions for copying, distribution and
  License.  Each licensee is addressed as "you".  "Licensees" and
receive it, in any medium, provided that you conspicuously and
    alternative is allowed only occasionally and noncommercially, and
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
provisionally, unless and until the copyright holder explicitly and
receives a license from the original licensors, to run, modify and
make, use, sell, offer for sale, import and otherwise run, modify and
				
			

Pesquisando qualquer caracter

O caracter de ponto final (.) é usado em expressões regulares para significar que qualquer caracter único pode existir no local especificado.

Por exemplo, para corresponder a qualquer coisa no arquivo GPL-3 que tenha dois caracteres e depois a string cept, você usaria o seguinte padrão:

				
					grep "..cept" GPL-3
				
			
Este comando retorna a seguinte saída:
				
					#Output
use, which is precisely where it is most unacceptable.  Therefore, we
infringement under applicable copyright law, except executing it on a
tells the user that there is no warranty for the work (except to the
License by making exceptions from one or more of its conditions.
form of a separately written license, or stated as exceptions;
  You may not propagate or modify a covered work except as expressly
  9. Acceptance Not Required for Having Copies.
...
				
			

Esta saída tem instâncias de acceptexcept e variações das duas palavras. O padrão também teria correspondido z2cept se isso também fosse encontrado.

Expressões de colchetes

Ao colocar um grupo de caracteres entre colchetes ( \[\]), você pode especificar que o caracter nessa posição pode ser qualquer caracter encontrado dentro do grupo de colchetes.

Por exemplo, para encontrar as linhas que contêm too ou two, você especificaria essas variações de forma sucinta usando o seguinte padrão:

				
					grep "t[wo]o" GPL-3
				
			
A saída mostra que ambas as variações existem no arquivo:
				
					#Output
your programs, too.
freedoms that you received.  You must make sure that they, too, receive
  Developers that use the GNU GPL protect your rights with two steps:
a computer network, with no transfer of a copy, is not conveying.
System Libraries, or general-purpose tools or generally available free
    Corresponding Source from a network server at no charge.
...
				
			

A notação de colchetes oferece algumas opções interessantes. Você pode fazer com que o padrão corresponda a qualquer coisa , exceto aos caracteres entre colchetes, iniciando a lista de caracteres entre colchetes com o caracter ^.

Este exemplo é semelhante ao padrão .ode, mas não corresponderá ao padrão code:

				
					grep "[^c]ode" GPL-3
				
			

O resultado será este:

				
					#Output
  1. Source Code.
    model, to give anyone who possesses the object code either (1) a
the only significant mode of use of the product.
notice like this when it starts in an interactive mode:
				
			

Observe que na segunda linha retornada existe, de fato, a palavra code. Isto não é uma falha da expressão regular ou do grep. Em vez disso, esta linha foi retornada porque anteriormente na linha, o padrão mode, encontrado na palavra model, foi encontrado. A linha foi retornada porque havia uma instância que correspondia ao padrão.

Outro recurso útil dos colchetes é que você pode especificar um intervalo de caracteres em vez de digitar individualmente cada caractere disponível.

Isso significa que se quiser encontrar todas as linhas que começam com letras maiúsculas, você pode usar o seguinte padrão:

				
					grep "^[A-Z]" GPL-3
				
			
Aqui está a saída que esta expressão retorna:
				
					#Output
GNU General Public License for most of our software; it applies also to
States should not allow patents to restrict development and use of
License.  Each licensee is addressed as "you".  "Licensees" and
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
System Libraries, or general-purpose tools or generally available free
Source.
User Product is transferred to the recipient in perpetuity or for a
...
				
			

Devido a alguns problemas de classificação herdados, geralmente é mais preciso usar classes de caracteres POSIX em vez de intervalos de caracteres como você acabou de usar.

Discutir cada classe de caracteres POSIX estaria além do escopo deste guia, mas um exemplo que realizaria o mesmo procedimento do exemplo anterior usa a classe de caracteres \[:upper:\] dentro de um seletor de colchetes:

				
					grep "^[[:upper:]]" GPL-3
				
			

A saída será a mesma de antes.

Repetir o padrão zero ou mais vezes

Por fim, um dos metacaracteres mais utilizados é o asterisco (*), que significa “repetir o caractere ou expressão anterior zero ou mais vezes”.

Para encontrar cada linha do arquivo GPL-3 que contém parênteses de abertura e fechamento, com apenas letras e espaços simples entre eles, use a seguinte expressão:

				
					grep "([A-Za-z ]*)" GPL-3
				
			

Você obterá a seguinte saída:

				
					#Output
 Copyright (C) 2007 Free Software Foundation, Inc.
distribution (with or without modification), making available to the
than the work as a whole, that (a) is included in the normal form of
Component, and (b) serves only to enable use of the work with that
(if any) on which the executable work runs, or a compiler used to
    (including a physical distribution medium), accompanied by the
    (including a physical distribution medium), accompanied by a
    place (gratis or for a charge), and offer equivalent access to the
...
				
			

Até agora você usou pontos, asteriscos e outros caracteres em suas expressões, mas às vezes você precisa procurar por esses caracteres especificamente.

Escapando Meta-Caracteres

Há momentos em que você precisará procurar um ponto literal ou um colchete de abertura literal, especialmente ao trabalhar com código-fonte ou arquivos de configuração. Como esses caracteres têm um significado especial em expressões regulares, você precisa “escapar” esses caracteres para informar  ao grep que não deseja usar seu significado especial neste caso.

Você escapa caracteres usando a barra invertida (\) na frente do caractere que normalmente teria um significado especial.

Por exemplo, para encontrar qualquer linha que comece com uma letra maiúscula e termine com um ponto final, use a seguinte expressão que escapa o ponto final para que represente um ponto final literal em vez do significado usual de “qualquer caractere”:

				
					grep "^[A-Z].*\.$" GPL-3
				
			

Esta é a saída que você verá:

				
					#Output
Source.
License by making exceptions from one or more of its conditions.
License would be to refrain entirely from conveying the Program.
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
SUCH DAMAGES.
Also add information on how to contact you by electronic and paper mail.
				
			

Agora vamos dar uma olhada em outras opções de expressões regulares.

Expressões regulares estendidas

O comando grep oferece suporte a uma linguagem de expressão regular mais extensa usando a flag -E ou chamando o comando egrep em vez de grep.

Essas opções abrem os recursos para as “expressões regulares estendidas”. Expressões regulares estendidas incluem todos os metacaracteres básicos, juntamente com metacaracteres adicionais para expressar correspondências mais complexas.

Agrupamento

Uma das habilidades mais úteis que as expressões regulares estendidas abrem é a capacidade de agrupar expressões para manipular ou referenciar como uma unidade.

Para agrupar expressões, coloque-as entre parênteses. Se desejar usar parênteses sem usar expressões regulares estendidas, você pode escapá-los com a barra invertida para ativar essa funcionalidade. Isso significa que as três expressões a seguir são funcionalmente equivalentes:

				
					grep "\(grouping\)" file.txt
grep -E "(grouping)" file.txt
egrep "(grouping)" file.txt
				
			

Alternância

Semelhante à forma como as expressões de colchetes podem especificar diferentes opções possíveis para correspondências de caracteres únicos, a alternância permite especificar correspondências alternativas para strings ou conjuntos de expressões.

Para indicar alternância, use a barra vertical pipe |. São frequentemente usados ​​em agrupamentos entre parênteses para especificar que uma de duas ou mais possibilidades deve ser considerada uma correspondência.

O seguinte comando encontrará GPL ou General Public License no texto:

				
					grep -E "(GPL|General Public License)" GPL-3
				
			
A saída é semelhante a esta:
				
					#Output
  The GNU General Public License is a free, copyleft license for
the GNU General Public License is intended to guarantee your freedom to
GNU General Public License for most of our software; it applies also to
price.  Our General Public Licenses are designed to make sure that you
  Developers that use the GNU GPL protect your rights with two steps:
  For the developers' and authors' protection, the GPL clearly explains
authors' sake, the GPL requires that modified versions be marked as
have designed this version of the GPL to prohibit the practice for those
...
				
			

A alternância pode selecionar entre mais de duas opções adicionando outras opções dentro do grupo de seleção separadas pelo caracter |.

Quantificadores

Assim como o metacaracter * que corresponde ao caracter ou conjunto de caracteres anterior ser encontrado zero ou mais vezes, existem outros metacaracteres disponíveis em expressões regulares estendidas que especificam o número de ocorrências.

Para corresponder a um caracter zero ou uma vez, você pode usar o caracter ?. Isso torna os caracteres ou conjuntos de caracteres anteriores opcionais, em essência.

O seguinte comando retorna as correspondências copyrightright colocando o copy em um grupo opcional:

				
					grep -E "(copy)?right" GPL-3
				
			

Esta será a saída:

				
					#Output
 Copyright (C) 2007 Free Software Foundation, Inc.
  To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights.  Therefore, you have
know their rights.
  Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
  "Copyright" also means copyright-like laws that apply to other kinds of
...
				
			

O caracter + corresponde a uma expressão que deve ser  encontrada uma ou mais vezes. É semelhante ao metacaracter *, mas com o +, a expressão deve corresponder pelo menos uma vez.

A expressão a seguir corresponde à string free mais um ou mais caracteres que não são caracteres de espaço em branco:

+caractere corresponde a uma expressão uma ou mais vezes. É quase como o *metacaractere, mas com o +caractere, a expressão deve corresponder pelo menos uma vez.

A expressão a seguir corresponde à string free seguida de um ou mais caracteres que não são caracteres de espaço em branco:

				
					grep -E "free[^[:space:]]+" GPL-3
				
			

Sendo este o resultado:

				
					#Output
  The GNU General Public License is a free, copyleft license for
to take away your freedom to share and change the works.  By contrast,
the GNU General Public License is intended to guarantee your freedom to
  When we speak of free software, we are referring to freedom, not
have the freedom to distribute copies of free software (and charge for
you modify it: responsibilities to respect the freedom of others.
freedomss that you received.  You must make sure that they, too, receive
protecting users' freedom to change the software.  The systematic
of the GPL, as needed to protect the freedom of users.
patents cannot be used to render the program non-free.
				
			

Especificando a repetição

Para especificar o número de vezes que uma correspondência deve ocorrer, use os caracteres entre chaves ( { }). Esses caracteres permitem especificar um número exato, um intervalo ou limites superiores ou inferiores para a quantidade de vezes que uma expressão pode corresponder.

Use a seguinte expressão para encontrar todas as linhas do arquivo  GPL-3 que contêm vogais triplas:

				
					grep -E "[AEIOUaeiou]{3}" GPL-3
				
			

Cada linha retornada contêm uma correspondência com três vogais seguidas:

				
					#Output
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
receive it, in any medium, provided that you conspicuously and
give under the previous paragraph, plus a right to possession of the
covered work so as to satisfy simultaneously your obligations under this
				
			

Para corresponder qualquer palavra que tenha entre 16 e 20 caracteres, use a seguinte expressão:

				
					grep -E "[[:alpha:]]{16,20}" GPL-3
				
			

Esta é a saída:

				
					#Output
    certain responsibilities if you distribute copies of the software, or if
    you modify it: responsibilities to respect the freedom of others.
        c) Prohibiting misrepresentation of the origin of that material, or
				
			

Somente linhas contendo palavras nesse comprimento são exibidas.

Conclusão

O grep é útil para encontrar padrões em arquivos ou na hierarquia do sistema de arquivos, portanto, vale a pena gastar algum tempo para se familiarizar com suas opções e sintaxe.

As expressões regulares são ainda mais versáteis e podem ser usadas com muitos programas populares. Por exemplo, muitos editores de texto implementam expressões regulares para pesquisar e substituir texto.

Além disso, a maioria das linguagens de programação modernas usam expressões regulares para executar procedimentos em dados específicos. Depois de entender as expressões regulares, você será capaz de transferir esse conhecimento para muitas tarefas comuns relacionadas ao computador, desde a realização de pesquisas avançadas em seu editor de texto até a validação de entradas do usuário.

Este artigo foi traduzido e adaptado para o Português pelo autor do post. O artigo original pode ser lido aqui.

Compartilhe: