Quer saber o que essas estranhas sequências de símbolos fazem no Linux? Eles oferecem magia de linha de comando! Vamos ensiná-lo a lançar feitiços de expressão regular e aumentar o nível de suas habilidades de linha de comando.
Índice
Expressões regulares ( regexes ) são uma maneira de encontrar sequências de caracteres correspondentes. Eles usam letras e símbolos para definir um padrão que é pesquisado em um arquivo ou fluxo. Existem vários sabores diferentes de regex. Vamos dar uma olhada na versão usada em utilitários e comandos comuns do Linux, como grep
o comando que imprime linhas que correspondem a um padrão de pesquisa .
Livros inteiros foram escritos sobre regexes, então este tutorial é apenas uma introdução. Existem regexes básicos e estendidos, e usaremos os estendidos aqui.
Para usar as expressões regulares estendidas com grep
, você deve usar a -E
opção (estendida). Como isso fica cansativo muito rapidamente, o egrep
comando foi criado. O egrep
comando é o mesmo que a grep -E
combinação, você apenas não precisa usar a -E
opção todas as vezes.
Se você achar mais conveniente usar egrep
, você pode. No entanto, esteja ciente de que ele está oficialmente obsoleto. Ainda está presente em todas as distribuições que verificamos, mas pode desaparecer no futuro.
Claro, você sempre pode fazer seus próprios aliases, portanto, suas opções favoritas estão sempre incluídas para você.
Para nossos exemplos, usaremos um arquivo de texto simples contendo uma lista de Geeks. Lembre-se de que você pode usar regexes com muitos comandos do Linux. Estamos usando apenas grep
uma maneira conveniente de demonstrá-los.
Aqui está o conteúdo do arquivo:
menos geek.txt
A primeira parte do arquivo é exibida.
Vamos começar com um padrão de pesquisa simples e procurar ocorrências da letra “o” no arquivo. Novamente, como estamos usando a opção -E
(regex estendido) em todos os nossos exemplos, digitamos o seguinte:
grep -E 'o' geeks.txt
Cada linha que contém o padrão de pesquisa é exibida e a letra correspondente é destacada. Fizemos uma pesquisa simples, sem restrições. Não importa se a letra aparece mais de uma vez, no final da string, duas vezes na mesma palavra ou mesmo ao lado dela.
Alguns nomes tinham dois O’s; digitamos o seguinte para listar apenas aqueles:
grep -E 'oo' geeks.txt
Nosso conjunto de resultados, como esperado, é muito menor e nosso termo de pesquisa é interpretado literalmente. Não significa nada além do que digitamos: caracteres duplos “o”.
Veremos mais funcionalidade com nossos padrões de pesquisa à medida que avançamos.
Se quiser grep
listar o número da linha das entradas correspondentes, você pode usar a opção -n
(número da linha). Isso é um grep
truque – não faz parte da funcionalidade do regex. No entanto, às vezes, você pode querer saber onde em um arquivo as entradas correspondentes estão localizadas.
Nós digitamos o seguinte:
grep -E -n 'o' geeks.txt
Outro grep
truque útil que você pode usar é a opção -o
(apenas correspondência). Ele exibe apenas a sequência de caracteres correspondente, não o texto ao redor. Isso pode ser útil se você precisar examinar rapidamente uma lista em busca de correspondências duplicadas em qualquer uma das linhas.
Para fazer isso, digitamos o seguinte:
grep -E -n -o 'o' geeks.txt
Se você quiser reduzir a produção ao mínimo, pode usar a -c
opção (contagem).
Nós digitamos o seguinte para ver o número de linhas no arquivo que contém correspondências:
grep -E -c 'o' geeks.txt
Se você quiser pesquisar ocorrências de “l” duplo e “o” duplo, você pode usar o |
caractere barra vertical ( ), que é o operador de alternância. Ele procura correspondências para o padrão de pesquisa à sua esquerda ou direita.
Nós digitamos o seguinte:
grep -E -n -o 'll | oo' geeks.txt
Qualquer linha contendo um duplo “l”, “o” ou ambos, aparece nos resultados.
Você também pode usar o operador de alternância para criar padrões de pesquisa, como este:
sou | sou
Isso corresponderá a “am” e “Am”. Para qualquer coisa diferente de exemplos triviais, isso leva rapidamente a padrões de pesquisa complicados. Uma maneira fácil de contornar isso é usar a opção -i
(ignorar maiúsculas e minúsculas) com grep
.
Para fazer isso, digitamos o seguinte:
grep -E 'am' geeks.txt
grep -E -i 'am' geeks.txt
O primeiro comando produz três resultados com três correspondências destacadas. O segundo comando produz quatro resultados porque o “Am” em “Amanda” também corresponde.
Podemos combinar a sequência “Am” de outras maneiras também. Por exemplo, podemos pesquisar esse padrão especificamente ou ignorar o caso e especificar que a sequência deve aparecer no início de uma linha.
Quando você combina sequências que aparecem na parte específica de uma linha de caracteres ou de uma palavra, isso é chamado de ancoragem. Use o ^
símbolo circunflexo ( ) para indicar que o padrão de pesquisa só deve considerar uma sequência de caracteres uma correspondência se ela aparecer no início de uma linha.
Nós digitamos o seguinte (observe que o circunflexo está entre aspas simples):
grep -E ‘Am’ geeks.txt
grep -E -i '^ am' geeks.txt
Ambos os comandos correspondem a “Am”.
Agora, vamos procurar linhas que contenham um duplo “n” no final de uma linha.
Digitamos o seguinte, usando um cifrão ( $
) para representar o final da linha:
grep -E -i 'nn' geeks.txt
grep -E -i 'nn $' geeks.txt
Você pode usar um ponto ( .
) para representar qualquer caractere único.
Digitamos o seguinte para pesquisar padrões que começam com “T”, terminam com “m” e têm um único caractere entre eles:
grep -E 'Tm' geeks.txt
O padrão de pesquisa correspondeu às sequências “Tim” e “Tom”. Você também pode repetir os pontos para indicar um certo número de caracteres.
Digitamos o seguinte para indicar que não nos importamos quais são os três caracteres do meio:
grep-E 'J ... n' geeks.txt
A linha contendo “Jason” é correspondida e exibida.
Use o asterisco ( *
) para corresponder a zero ou mais ocorrências do caractere anterior. Neste exemplo, o caractere que precederá o asterisco é o ponto ( .
), que (novamente) significa qualquer caractere.
Isso significa que o asterisco ( *
) corresponderá a qualquer número (incluindo zero) de ocorrências de qualquer caractere.
O asterisco às vezes é confuso para iniciantes em regex. Talvez seja porque eles geralmente o usam como um caractere curinga que significa “qualquer coisa”.
Em expressões regulares, porém, 'c*t'
não corresponde a “gato”, “cot,” “galeirão”, etc. Em vez disso, se traduz como “corresponde a zero ou mais caracteres ‘c’, seguidos por um ‘t’”. Portanto, corresponde a “t”, “ct”, “cct”, “ccct” ou qualquer número de caracteres “c”.
Como sabemos o formato do conteúdo em nosso arquivo, podemos adicionar um espaço como o último caractere no padrão de pesquisa. Um espaço só aparece em nosso arquivo entre o nome e o sobrenome.
Portanto, digitamos o seguinte para forçar a pesquisa a incluir apenas os primeiros nomes do arquivo:
grep -E 'J. * n' geeks.txt
grep -E 'J. * n' geeks.txt
À primeira vista, os resultados do primeiro comando parecem incluir algumas correspondências estranhas. No entanto, todos eles correspondem às regras do padrão de pesquisa que usamos.
A sequência deve começar com um “J” maiúsculo, seguido por qualquer número de caracteres e, em seguida, um “n”. Ainda assim, embora todas as correspondências comecem com “J” e terminem com “n”, algumas delas não são o que você esperava.
Como adicionamos o espaço no segundo padrão de pesquisa, obtivemos o que pretendíamos: todos os primeiros nomes que começam com “J” e terminam com “n”.
Digamos que desejamos encontrar todas as linhas que começam com “N” ou “W” maiúsculo.
Se usarmos o seguinte comando, ele corresponde a qualquer linha com uma sequência que começa com “N” ou “W” maiúsculo, não importa onde apareça na linha:
grep -E 'N | W' geeks.txt
Não é isso que queremos. Se aplicarmos a âncora de início de linha ( ^
) no início do padrão de pesquisa, conforme mostrado abaixo, obteremos o mesmo conjunto de resultados, mas por um motivo diferente:
grep -E '^ N | W' geeks.txt
A pesquisa corresponde a linhas que contêm um “W” maiúsculo, em qualquer lugar da linha. Também corresponde à linha “Chega” porque começa com “N” maiúsculo. A âncora de início de linha ( ^
) é aplicada apenas ao “N” maiúsculo
Também poderíamos adicionar uma âncora de início de linha a “W” maiúsculo, mas isso logo se tornaria ineficiente em um padrão de pesquisa mais complicado do que nosso exemplo simples.
A solução é colocar parte de nosso padrão de pesquisa entre colchetes ( []
) e aplicar o operador âncora ao grupo. Os colchetes ( []
) significam “qualquer caractere desta lista”. Isso significa que podemos omitir o |
operador de alternância ( ) porque não precisamos dele.
Podemos aplicar a âncora de início de linha a todos os elementos da lista entre colchetes ( []
). (Observe que a âncora do início da linha está fora dos colchetes).
Digitamos o seguinte para pesquisar qualquer linha que comece com “N” ou “W” maiúsculo:
grep -E '^ [NW]' geeks.txt
Usaremos esses conceitos no próximo conjunto de comandos também.
Nós digitamos o seguinte para pesquisar qualquer pessoa chamada Tom ou Tim:
grep -E 'T [oi] m' geeks.txt
Se o acento circunflexo ( ^
) for o primeiro caractere entre colchetes ( []
), o padrão de pesquisa procura por qualquer caractere que não apareça na lista.
Por exemplo, digitamos o seguinte para procurar qualquer nome que comece com “T”, termine com “m” e em que a letra do meio não seja “o”:
grep -E 'T [^ o] m' geeks.txt
Podemos incluir qualquer número de caracteres na lista. Digitamos o seguinte para procurar nomes que começam com “T”, terminam em “m” e contêm qualquer vogal no meio:
grep -E 'T [aeiou] m' geeks.txt
Você pode usar expressões de intervalo para especificar o número de vezes que deseja que o caractere ou grupo anterior seja encontrado na string correspondente. Você coloca o número entre chaves ( {}
).
Um número por si só significa especificamente esse número, mas se você segui-lo com uma vírgula ( ,
), significa esse número ou mais. Se você separar dois números com uma vírgula ( 1,2
), significa o intervalo de números do menor ao maior.
Queremos procurar nomes que começam com “T”, são seguidos por pelo menos uma, mas não mais do que duas, vogais consecutivas e terminam em “m”.
Então, digitamos este comando:
grep -E 'T [aeiou] {1,2} m' geeks.txt
Isso corresponde a “Tim”, “Tom” e “Equipe”.
Se quisermos pesquisar a sequência “el”, digitamos o seguinte:
grep -E 'el' geeks.txt
Adicionamos um segundo “l” ao padrão de pesquisa para incluir apenas as sequências que contêm “l” duplo:
grep -E 'ell' geeks.txt
Isso é equivalente a este comando:
grep -E 'el {2}' geeks.txt
Se fornecermos um intervalo de “pelo menos uma e não mais do que duas” ocorrências de “l”, ela corresponderá às sequências “el” e “ell”.
Isso é sutilmente diferente dos resultados do primeiro desses quatro comandos, em que todas as correspondências eram para sequências “el”, incluindo aquelas dentro das sequências “ell” (e apenas um “l” é destacado).
Nós digitamos o seguinte:
grep -E 'el {1,2}' geeks.txt
Para encontrar todas as sequências de duas ou mais vogais, digitamos este comando:
grep -E '[aeiou] {2,}' geeks.txt
Digamos que desejamos encontrar linhas nas quais um ponto ( .)
é o último caractere. Sabemos que o cifrão ( $
) é a âncora do fim da linha, então podemos digitar o seguinte:
grep -E '. $' geeks.txt
No entanto, conforme mostrado abaixo, não recebemos o que esperávamos.
Conforme abordamos anteriormente, o ponto final ( .
) corresponde a qualquer caractere único. Como cada linha termina com um caractere, todas as linhas são retornadas nos resultados.
Então, como você evita que um caractere especial execute sua função regex quando você deseja apenas pesquisar esse caractere real? Para fazer isso, você usa uma barra invertida ( \
) para escapar do caractere.
Um dos motivos pelos quais estamos usando as -E
opções (estendidas) é porque elas exigem muito menos escape quando você usa as expressões regulares básicas.
Nós digitamos o seguinte:
grep -e '\. $' geeks.txt
Corresponde ao caractere de ponto .
final ( ) no final de uma linha.
Abordamos as âncoras de início ( ^
) e fim de linha ( $
) acima. No entanto, você pode usar outras âncoras para operar nos limites das palavras.
Nesse contexto, uma palavra é uma sequência de caracteres delimitada por espaços em branco (o início ou o fim de uma linha). Portanto, “psy66oh” contaria como uma palavra, embora você não a encontre em um dicionário.
O início da palavra âncora é ( \<
); observe que ele aponta para a esquerda, para o início da palavra. Digamos que um nome foi digitado por engano em letras minúsculas. Podemos usar a -i
opção grep para realizar uma pesquisa que não diferencia maiúsculas de minúsculas e encontrar nomes que começam com “h”.
Nós digitamos o seguinte:
grep -E -i 'h' geeks.txt
Isso encontra todas as ocorrências de “h”, não apenas aquelas no início das palavras.
grep -E -i '\ <h' geeks.txt
Isso encontra apenas aqueles no início das palavras.
Vamos fazer algo semelhante com a letra “y”; queremos apenas ver as instâncias em que está no final de uma palavra. Nós digitamos o seguinte:
grep -E 'y' geeks.txt
Isso encontra todas as ocorrências de “y”, onde quer que apareça nas palavras.
Agora, digitamos o seguinte, usando o final da palavra âncora ( />
) (que aponta para a direita, ou o final da palavra):
grep -E 'y \>' geeks.txt
O segundo comando produz o resultado desejado.
Para criar um padrão de pesquisa que procure uma palavra inteira, você pode usar o operador de limite ( \b
). Usaremos o operador de limite ( \B
) em ambas as extremidades do padrão de pesquisa para encontrar uma sequência de caracteres que deve estar dentro de uma palavra maior:
grep -E '\ bGlenn \ b' geeks.txt
grep -E '\ Bway \ B' geeks.txt
Você pode usar atalhos para especificar as listas nas classes de caracteres. Esses indicadores de intervalo evitam que você precise digitar todos os membros de uma lista no padrão de pesquisa.
Você pode usar todos os seguintes:
Você também pode usar quantas classes de caracteres desejar em um padrão de pesquisa. O seguinte padrão de pesquisa corresponde a sequências que começam com “J”, seguido por um “o” ou “s” e, em seguida, um “e”, “h”, “l” ou “s”:
grep -E 'J [os] [ehls]' geeks.txt
Em nosso próximo comando, usaremos o a-z
especificador de intervalo.
Nosso comando de pesquisa divide desta forma:
Reunimos tudo no seguinte comando:
grep -E 'H [az] * man' geeks.txt
Algumas regexes podem se tornar rapidamente difíceis de analisar visualmente. Quando as pessoas escrevem regexes complicadas, geralmente começam pequenas e adicionam mais e mais seções até que funcione. Eles tendem a aumentar em sofisticação com o tempo.
Quando você tenta retroceder a partir da versão final para ver o que ela faz, é um desafio totalmente diferente.
Por exemplo, observe este comando:
grep -E '^ ([0-9] {4} [-]) {3} [0-9] {4} | [0-9] {16}' geeks.txt
Por onde você começaria a desembaraçar isso? Vamos começar do início e pegar um pedaço de cada vez:
[0-9]
. Nosso primeiro caractere, então, é um dígito de zero a nove. A seguir, temos uma expressão de intervalo que contém o número quatro {4}
. Isso se aplica ao nosso primeiro caractere, que sabemos ser um dígito. Portanto, a primeira parte do padrão de pesquisa agora tem quatro dígitos. Ele pode ser seguido por um espaço ou um hífen ( [- ]
) de outra classe de caracteres.[0-9]
. Isso adiciona outro caractere ao padrão de pesquisa e pode ser qualquer dígito de zero a nove.Portanto, nosso padrão de pesquisa procurará um dos seguintes:
-
).Os resultados são mostrados abaixo.
Este padrão de pesquisa procura formas comuns de escrever números de cartão de crédito. Também é versátil o suficiente para encontrar estilos diferentes, com um único comando.
A complexidade geralmente é apenas um monte de simplicidade unida. Depois de compreender os blocos de construção fundamentais, você pode criar utilitários eficientes e poderosos e desenvolver novas habilidades valiosas.
Muitos aplicativos de limpeza estão disponíveis para Windows ao longo dos anos, mas hoje em…
Seu PlayStation 4 está congelado? Seus jogos favoritos continuam travando? Reiniciar seu PS4 pode resolver…
A popularidade das mensagens de texto significou aprender uma forma totalmente nova de comunicação. Você…
A foto dos "Pilares da Criação" tirada pelo Telescópio Espacial Hubble é uma das fotos…
O Proton Drive saiu de seu estágio beta há algumas semanas, mas o aplicativo real…
Para ver suas fotos mais de perto ou para uma edição precisa , você pode…