Pesquisa reversa em REGEX

regex_reverso-1_abertura

Dica rápida com expressões regulares. Quando você precisa buscar uma determinada palavra dentro de uma sequência¹ você faz algo mais ou menos assim…

$ lspci | egrep "^00:1[0-9]\.[0-9]"
00:14.0 USB controller: Intel Corporation Sunrise Point-LP USB 3.0...
00:14.2 Signal processing controller: Intel Corporation Sunrise Po...
00:15.0 Signal processing controller: Intel Corporation Sunrise Po...
00:16.0 Communication controller: Intel Corporation Sunrise Point-...
00:17.0 SATA controller: Intel Corporation Sunrise Point-LP SATA C...

Mas e se você deseja justamente fazer o contrário? No caso específico do comando grep basta simplesmente utilizar o parâmetro ou “– – invert-match“|”-v” para tal…

$ lspci | egrep --invert-match "^00:1[0-9]\.[0-9]"
00:00.0 Host bridge: Intel Corporation Xeon E3-1200 v6/7th Gen Cor...
00:02.0 VGA compatible controller: Intel Corporation HD Graphics 6...
00:1c.0 PCI bridge: Intel Corporation Sunrise Point-LP PCI Express...
00:1c.5 PCI bridge: Intel Corporation Sunrise Point-LP PCI Express...
00:1f.0 ISA bridge: Intel Corporation Device 9d4e (rev 21)
00:1f.2 Memory controller: Intel Corporation Sunrise Point-LP PMC... 
00:1f.3 Audio device: Intel Corporation Sunrise Point-LP HD Audio... 
00:1f.4 SMBus: Intel Corporation Sunrise Point-LP SMBus (rev 21)
01:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL81...
02:00.0 Network controller: Qualcomm Atheros QCA9377 802.11ac Wire...

Mas e se o que você precisa, não pode ser feito através do grep?

(¹) Uma pesquisa simples, tudo que comece com “00:1”, tenha qualquer dígito entre  0 e 9, um ponto (“.”) e outro dígito entre 0 e 9.

É possível usar o “^” para negar elementos de uma lista de caracteres mas ele justamente serve para listas de caracteres e não para uma sequência definida. Assim, será preciso usar o (?!«…») e escrever uma expressão que contém duas condições.

^(?!00:1[0-9]\.[0-9]).*$

Como a parte em laranja já foi explicada, vamos ao resto:

  1. No começo da linha (“^“).
  2. Qualquer coisa (“.*“) até o final da linha (“$“) — a 1ª condição.
  3. Que não case (“?!“) com este determinado padrão (a parte laranja) — a 2ª  condição.

O resultado…

$ lspci | grep --perl-regexp '^(?!00:1[0-9]\.[0-9]).*$'
00:00.0 Host bridge: Intel Corporation Xeon E3-1200 v6/7th Gen Cor...
00:02.0 VGA compatible controller: Intel Corporation HD Graphics 6...
00:1c.0 PCI bridge: Intel Corporation Sunrise Point-LP PCI Express...
00:1c.5 PCI bridge: Intel Corporation Sunrise Point-LP PCI Express...
00:1f.0 ISA bridge: Intel Corporation Device 9d4e (rev 21)
00:1f.2 Memory controller: Intel Corporation Sunrise Point-LP PMC ... 
00:1f.3 Audio device: Intel Corporation Sunrise Point-LP HD Audio ...
00:1f.4 SMBus: Intel Corporation Sunrise Point-LP SMBus (rev 21)
01:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL81...
02:00.0 Network controller: Qualcomm Atheros QCA9377 802.11ac Wire...

Neste caso é necessário executar o grep com o suporte à sintaxe de expressões regulares do Perl — parâmetro “– – perl-regexp“|”-P” ao invés da sintaxe disponível apenas com o suporte estendido².

E já que o Perl foi citado…

$ lspci | perl -ne 'printf if /^(?!00:1[0-9]\.[0-9]).*$/'

É possível obter o mesmo resultado através da própria linguagem e, neste caso, com um programa de apenas uma só linha! 🙂

Até!

(²) Obtido através do parâmetro “– – extended-regexp“|”-E” ou simplesmente usando o egrep!

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s