Pesquisa de site

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:

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

Se você 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 inicial com o seguinte comando:

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

Se você 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 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:

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

  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, 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:

  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 \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:

  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 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:

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

  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

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:

  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 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:

  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 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:

  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, 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:

  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 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 :

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

  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 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:

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

  1. grep "\(grouping\)" file.txt
  2. grep -E "(grouping)" file.txt
  3. 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:

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

  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 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:

  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.

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:

  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 qualquer palavra que tenha 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

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.