Usando Grep e expressões regulares para procurar 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 \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. Esse programa aparentemente trivial é extremamente poderoso; sua capacidade de classificar a entrada com base em regras complexas o torna um link 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. Pode ser um servidor virtual privado ao qual você se conectou com SSH ou sua máquina local. Observe que este tutorial foi validado usando um servidor Linux executando o Ubuntu 20.04, mas os exemplos fornecidos devem funcionar em um computador executando qualquer versão de qualquer distribuição Linux.
Se você planeja usar um servidor remoto para seguir este guia, recomendamos que você primeiro conclua nosso guia Configuração inicial do servidor. Fazendo isso, você terá um ambiente de servidor seguro — incluindo um usuário não root com privilégios sudo
e um firewall configurado com UFW — que você pode usar para desenvolver suas habilidades em Linux.
Uso Básico
Neste tutorial, você usará grep
para pesquisar a GNU General Public License versão 3 para várias palavras e frases.
Se você estiver em um sistema Ubuntu, poderá encontrar o arquivo na pasta /usr/share/common-licenses
. Copie-o para o seu diretório pessoal:
- cp /usr/share/common-licenses/GPL-3 .
Se você estiver em outro sistema, use o comando curl
para baixar uma cópia:
- curl -o GPL-3 https://www.gnu.org/licenses/gpl-3.0.txt
Você também usará o arquivo de licença BSD neste tutorial. No Linux, você pode copiá-lo para seu diretório inicial com o seguinte comando:
- cp /usr/share/common-licenses/BSD .
Se você estiver em outro sistema, crie o arquivo com o seguinte comando:
- cat << 'EOF' > BSD
- Copyright (c) The Regents of the University of California.
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. Neither the name of the University nor the names of its contributors
- 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
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
- EOF
Agora que você tem os arquivos, pode começar a trabalhar com grep
.
Na forma mais básica, você usa grep
para combinar padrões literais dentro de um arquivo de texto. Isso significa que se você passar grep
uma palavra para procurar, ele imprimirá todas as linhas do arquivo que contém essa palavra.
Execute o seguinte comando para usar grep
para 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 que você pesquisou será destacado na saída.
Opções Comuns
Por padrão, grep
procurará o padrão exato especificado no arquivo de entrada e retornará as linhas que encontrar. Você pode tornar esse comportamento mais útil adicionando alguns sinalizadores opcionais ao grep
.
Se você deseja que o grep
ignore o \case do seu parâmetro de pesquisa e procure variações de letras maiúsculas e minúsculas, você pode especificar -i
ou --ignore-case
.
Pesquise cada instância da palavra license
(com letras maiúsculas, minúsculas ou mistas) no mesmo arquivo anterior com o seguinte comando:
- grep -i "license" GPL-3
Os resultados contêm: LICENSE
, license
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 seria retornada.
Se você deseja localizar todas as linhas que não contêm um padrão especificado, 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ê receberá esta saída:
OutputAll 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 \ignore case, os dois últimos itens foram retornados como não tendo a palavra the
.
Geralmente é ú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:
Output2: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 fazer referência ao número da linha se quiser fazer alterações em todas as linhas que não contêm the
. Isso é especialmente útil ao trabalhar com código-fonte.
Expressões regulares
Na introdução, você aprendeu que grep
significa \impressão de expressão regular global. Uma \expressão regular é uma string de texto que descreve um padrão de pesquisa específico.
Diferentes aplicativos e linguagens de programação implementam expressões regulares de maneira ligeiramente diferente. Neste tutorial, você explorará apenas um pequeno subconjunto da maneira como o grep
descreve seus padrões.
Correspondências Literais
Nos exemplos anteriores deste tutorial, quando você pesquisou pelas palavras GNU
e the
, na verdade você estava procurando por expressões regulares básicas que correspondiam à sequência exata de caracteres GNU
e o
. Os padrões que especificam exatamente os caracteres a serem correspondidos são chamados de literais porque correspondem ao padrão literalmente, caractere por caractere.
É útil pensar neles como correspondendo a uma sequência de caracteres em vez de corresponder a uma palavra. Isso se tornará uma distinção mais importante à medida que você aprender padrões mais complexos.
Todos os caracteres alfabéticos e numéricos (assim como alguns outros caracteres) são correspondidos literalmente, a menos que sejam modificados por outros mecanismos de expressão.
Partidas âncora
Â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 a GNU
bem no início da linha. Para fazer isso, você pode usar a âncora ^
antes da string literal.
Execute o seguinte comando para pesquisar o arquivo GPL-3
e encontrar linhas onde GNU
ocorre bem no início de uma linha:
- grep "^GNU" GPL-3
Este comando retornará as duas linhas a seguir:
OutputGNU 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ê usa a âncora $
no final de um padrão para indicar que a correspondência só será válida se ocorrer no final de uma linha.
Este comando corresponderá a todas as linhas que terminam com a palavra e
no arquivo GPL-3
:
- grep "and$" GPL-3
Você receberá esta saída:
Outputthat 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
Correspondendo a qualquer caractere
O caractere de ponto (.) é usado em expressões regulares para significar que qualquer caractere único pode existir no local especificado.
Por exemplo, para corresponder a qualquer coisa no arquivo GPL-3
que tenha dois caracteres e, em seguida, a string cept
, você deve usar o seguinte padrão:
- grep "..cept" GPL-3
Este comando retorna a seguinte saída:
Outputuse, 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 accept
e except
e variações das duas palavras. O padrão também teria correspondido a z2cept
se ele também fosse encontrado.
Expressões de colchetes
Ao colocar um grupo de caracteres entre colchetes (\[
e \]
), você pode especificar que o caractere nessa posição pode ser qualquer caractere encontrado dentro do grupo de colchetes.
Por exemplo, para localizar as linhas que contêm too
ou two
, especifique essas variações sucintamente usando o seguinte padrão:
- grep "t[wo]o" GPL-3
A saída mostra que ambas as variações existem no arquivo:
Outputyour 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 os caracteres entre colchetes, iniciando a lista de caracteres entre colchetes com um caractere ^
.
Este exemplo é como o padrão .ode
, mas não corresponderá ao padrão code
:
- grep "[^c]ode" GPL-3
Aqui está a saída que você receberá:
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
. Isso não é uma falha da expressão regular ou grep. Em vez disso, esta linha foi retornada porque anteriormente na linha, o padrão mode
, encontrado dentro da 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 você deseja localizar todas as linhas que começam com letra maiúscula, pode usar o seguinte padrão:
- grep "^[A-Z]" GPL-3
Aqui está a saída que esta expressão retorna:
OutputGNU 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 legados, 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.
Repita o padrão zero ou mais vezes
Por fim, um dos metacaracteres mais usados é o asterisco, ou *
, que significa \repetir o caractere ou expressão anterior zero ou mais vezes.
Para localizar cada linha no arquivo GPL-3
que contém um parêntese de abertura e fechamento, com apenas letras e espaços simples entre elas, 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 dizer ao grep
que não deseja usar seu significado especial neste caso.
Você escapa caracteres usando o caractere de 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, use a seguinte expressão que escapa do ponto final para que represente um ponto literal em vez do significado usual de qualquer caractere:
- grep "^[A-Z].*\.$" GPL-3
Esta é a saída que você verá:
OutputSource.
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 ver outras opções de expressão regular.
Expressões Regulares Estendidas
O comando grep
suporta uma linguagem de expressão regular mais extensa usando o sinalizador -E
ou chamando o comando egrep
em vez de grep
.
Essas opções abrem os recursos de expressões regulares estendidas. As 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 quiser usar parênteses sem usar expressões regulares estendidas, você pode escapá-los com a barra invertida para habilitar 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 a como as expressões de colchetes podem especificar diferentes opções possíveis para correspondências de um único caractere, a alternância permite especificar correspondências alternativas para cadeias de caracteres ou conjuntos de expressões.
Para indicar alternância, use a barra vertical |
. Estes são frequentemente usados dentro do agrupamento entre parênteses para especificar que uma de duas ou mais possibilidades deve ser considerada uma correspondência.
O seguinte encontrará GPL
ou General Public License
no texto:
- grep -E "(GPL|General Public License)" GPL-3
A saída se parece com isto:
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 opções adicionais dentro do grupo de seleção separadas por caracteres pipe (|
) adicionais.
Quantificadores
Assim como o metacaractere *
que corresponde ao caractere ou conjunto de caracteres anterior zero ou mais vezes, há outros metacaracteres disponíveis em expressões regulares estendidas que especificam o número de ocorrências.
Para corresponder a um caractere zero ou uma vez, você pode usar o caractere ?
. Isso torna os conjuntos de caracteres ou caracteres que vieram antes opcionais, em essência.
O seguinte corresponde a copyright
e right
colocando copy
em um grupo opcional:
- grep -E "(copy)?right" GPL-3
Você receberá esta 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 caractere +
corresponde a uma expressão uma ou mais vezes. Isso é quase como o metacaractere *
, mas com o caractere +
, a expressão deve corresponder pelo menos uma vez.
A seguinte expressão corresponde à string free
mais um ou mais caracteres que não sejam caracteres de espaço em branco:
- grep -E "free[^[:space:]]+" GPL-3
Você verá esta saída:
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 da Partida
Para especificar o número de vezes que uma correspondência é repetida, use os caracteres de chave ({
e }
). Esses caracteres permitem que você especifique um número exato, um intervalo ou um limite superior ou inferior para a quantidade de vezes que uma expressão pode corresponder.
Use a seguinte expressão para localizar todas as linhas no arquivo GPL-3
que contêm vogais triplas:
- grep -E "[AEIOUaeiou]{3}" GPL-3
Cada linha retornada tem uma palavra com três vogais:
Outputchanged, 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 a qualquer palavra que tenha entre 16 e 20 caracteres, use a seguinte expressão:
- grep -E "[[:alpha:]]{16,20}" GPL-3
Aqui está a saída deste comando:
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 as linhas contendo palavras dentro desse comprimento são exibidas.
Conclusão
grep
é útil para encontrar padrões dentro de arquivos ou dentro da hierarquia do sistema de arquivos, então vale a pena gastar 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 usa expressões regulares para executar procedimentos em dados específicos. Depois de entender as expressões regulares, você poderá 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 da entrada do usuário.