Usando Grep e Expressões Regulares para Buscar 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 global de expressão regular”. Isso significa que você pode usar o grep para verificar se a entrada que ele recebe corresponde a um padrão especificado. Este programa aparentemente trivial é extremamente poderoso; sua capacidade de classificar a entrada com base em regras complexas o torna um elo popular em muitas cadeias de comandos.

Neste tutorial, você explorará as opções do comando grep, e então mergulhará no uso de expressões regulares para realizar buscas mais avançadas.

Pré-requisitos

Para acompanhar este guia, você precisará de acesso a um computador executando um sistema operacional baseado em Linux. Isso 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, incentivamos você a primeiro completar nosso Guia de Configuração Inicial do Servidor. Fazê-lo irá configurá-lo com um ambiente de servidor seguro — incluindo um usuário não-root com privilégios de sudo e um firewall configurado com UFW — que você pode usar para desenvolver suas habilidades no Linux.

Uso Básico

Neste tutorial, você usará grep para buscar a Licença Pública Geral GNU versão 3 por várias palavras e frases.

Se você estiver em um sistema Ubuntu, pode encontrar o arquivo na pasta /usr/share/common-licenses. Copie-o para seu diretório pessoal:

  1. cp /usr/share/common-licenses/GPL-3 .

Se estiver em outro sistema, use o comando curl para baixar uma cópia:

  1. 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 pessoal com o seguinte comando:

  1. cp /usr/share/common-licenses/BSD .

Se estiver em outro sistema, crie o arquivo com o seguinte comando:

  1. cat << 'EOF' > BSD
  2. Copyright (c) The Regents of the University of California.
  3. All rights reserved.
  4. Redistribution and use in source and binary forms, with or without
  5. modification, are permitted provided that the following conditions
  6. are met:
  7. 1. Redistributions of source code must retain the above copyright
  8. notice, this list of conditions and the following disclaimer.
  9. 2. Redistributions in binary form must reproduce the above copyright
  10. notice, this list of conditions and the following disclaimer in the
  11. documentation and/or other materials provided with the distribution.
  12. 3. Neither the name of the University nor the names of its contributors
  13. may be used to endorse or promote products derived from this software
  14. without specific prior written permission.
  15. THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  16. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18. ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  19. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  21. OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  22. HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  23. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  24. OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  25. SUCH DAMAGE.
  26. EOF

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

Na forma mais básica, você usa grep para corresponder padrões literais dentro de um arquivo de texto. Isso significa que se você passar grep uma palavra para buscar, ele imprimirá todas as linhas no arquivo contendo essa palavra.

Execute o seguinte comando para usar grep para buscar cada linha que contenha a palavra GNU:

  1. grep "GNU" GPL-3

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

O resultado resultante será cada linha contendo o texto do 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 irá buscar o padrão especificado exato dentro do arquivo de entrada e retornar as linhas encontradas. Você pode tornar esse comportamento mais útil adicionando algumas flags opcionais ao grep.

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

Procure por cada instância da palavra license (com caixa alta, caixa baixa ou mista) no mesmo arquivo que antes com o seguinte comando:

  1. 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, essa também teria sido retornada.

Se você deseja encontrar todas as linhas que não contenham um padrão específico, você pode usar a opção -v ou --invert-match.

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

  1. grep -v "the" BSD

Você receberá 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 não contendo a palavra the.

É frequentemente ú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 esta bandeira adicionada:

  1. 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 fazer referência ao número da linha se quiser fazer alterações em cada linha que não contenha the. Isso é especialmente útil ao trabalhar com código-fonte.

Expressões Regulares

Na introdução, você aprendeu que grep significa “global regular expression print”. 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 um pouco diferente. Neste tutorial, você estará explorando apenas um pequeno subconjunto da maneira como o grep descreve seus padrões.

Coincidências Literais

Nos exemplos anteriores deste tutorial, quando você procurou pelas palavras GNU e the, na verdade estava buscando por expressões regulares básicas que correspondessem exatamente à sequência de caracteres GNU e the. 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 (bem como certos outros caracteres) são correspondidos literalmente, a menos que sejam modificados por outros mecanismos de expressão.

Coincidências de Â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 a GNU no início exato da linha. Para fazer isso, você pode usar a âncora ^ antes da sequência literal.

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

  1. grep "^GNU" GPL-3

Este comando retornará as seguintes duas linhas:

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 o âncora $ no final de um padrão para indicar que a correspondência será válida apenas se ocorrer no final de uma linha.

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

  1. 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

Coincidindo com Qualquer Caractere

O caractere ponto (.) é usado em expressões regulares para significar que qualquer caractere único pode existir na localização especificada.

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

  1. 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 possui instâncias de tanto accept quanto except e variações das duas palavras. O padrão também teria correspondido a z2cept se fosse encontrado também.

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 um dos caracteres encontrados 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:

  1. 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 o padrão coincidir com qualquer coisa exceto os caracteres dentro de um colchete começando a lista de caracteres dentro dos colchetes com o caractere ^.

Este exemplo é como o padrão .ode, mas não coincidirá com o padrão code:

  1. 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, de fato, há a palavra code. Isso não é uma falha da expressão regular ou do grep. Na verdade, esta linha foi retornada porque anteriormente na linha, o padrão mode, encontrado na palavra model, foi encontrado. A linha foi retornada porque houve uma instância que coincidiu com o padrão.

Outra característica ú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ê quiser encontrar cada linha que começa com uma letra maiúscula, pode usar o seguinte padrão:

  1. 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 ordenação legados, muitas vezes é mais preciso usar classes de caracteres POSIX em vez de intervalos de caracteres como você acabou de usar.

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

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

A saída será a mesma que antes.

Repetir Padrão Zero ou Mais Vezes

Finalmente, um dos meta-caracteres mais comumente usados é o asterisco, ou *, que significa “repetir o caractere ou expressão anterior zero ou mais vezes”.

Para encontrar cada linha no arquivo GPL-3 que contenha um parêntese de abertura e fechamento, com apenas letras e espaços simples entre eles, use a seguinte expressão:

  1. 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 precisa procurar esses caracteres especificamente.

Escapando Meta-Caracteres

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

Você escapa caracteres usando o caractere 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 período, use a seguinte expressão que escapa o período final para que ele represente um período literal em vez do significado usual de “qualquer caractere”:

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

Este é o resultado 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 olhar para outras opções de expressão regular.

Expressões Regulares Estendidas

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

Essas opções abrem as capacidades das “expressões regulares estendidas”. As expressões regulares estendidas incluem todos os meta-caracteres básicos, juntamente com meta-caracteres adicionais para expressar correspondências mais complexas.

Agrupamento

Uma das habilidades mais úteis que as expressões regulares estendidas possibilitam é a capacidade de agrupar expressões juntas para manipulá-las ou referenciá-las como uma unidade.

Para agrupar expressões juntas, coloque-as entre parênteses. Se você deseja usar parênteses sem utilizar expressões regulares estendidas, 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:

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

Alternância

Semelhante a como as expressões entre colchetes podem especificar diferentes escolhas possíveis para correspondências de caracteres únicos, a alternância permite que você especifique correspondências alternativas para strings ou conjuntos de expressões.

Para indicar alternância, use o caractere de barra vertical |. Esses são frequentemente usados dentro de grupos parentéticos para especificar que uma das duas ou mais possibilidades deve ser considerada uma correspondência.

O seguinte irá encontrar tanto GPL quanto General Public License no texto:

  1. grep -E "(GPL|General Public License)" GPL-3

A saída se parece com isso:

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 escolhas adicionando escolhas adicionais dentro do grupo de seleção separadas por caracteres de barra vertical (|).

Quantificadores

Assim como o meta-caractere * que corresponde ao caractere anterior ou conjunto de caracteres zero ou mais vezes, existem outros meta-caracteres 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 opcional o caractere ou conjunto de caracteres que veio antes, essencialmente.

O seguinte corresponde a copyright e right ao colocar copy em um grupo opcional:

  1. 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 meta-caractere *, mas com o caractere +, a expressão deve corresponder pelo menos uma vez.

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

  1. 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.

Especificar a Repetição da Correspondência

Para especificar o número de vezes que uma correspondência é repetida, use os caracteres de chaves ({ e }). Esses caracteres permitem que você especifique 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 no arquivo GPL-3 que contenham triplo-vogais:

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

Cada linha retornada tem uma palavra com três vogais:

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 a palavras que tenham entre 16 e 20 caracteres, use a seguinte expressão:

  1. 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

Apenas as linhas contendo palavras com esse 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 dedicar 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 buscar e substituir texto.

Além disso, a maioria das linguagens de programação modernas usa expressões regulares para realizar procedimentos em partes específicas de dados. Uma vez que você entende as expressões regulares, poderá transferir esse conhecimento para muitas tarefas comuns relacionadas a computadores, desde realizar buscas avançadas em seu editor de texto até validar a entrada do usuário.

Source:
https://www.digitalocean.com/community/tutorials/using-grep-regular-expressions-to-search-for-text-patterns-in-linux