Problemas com “+” no grep

7

Estou tentando escrever um comando grep para encontrar linhas como as abaixo em um arquivo de texto grande:

<div class="node_thumbnail" data-type="file" name="GOPR0036.MP4_frame000001.jpg" data="813334c25191468c9f1c57afc99fde60" aid="133948" rel="/Files/ToolTipView?fileId=813334c25191468c9f1c57afc99fde60&pageNo=1&NoCache=101016083044" rev="topMiddle">

mas o símbolo + parece estar causando problemas nos comandos abaixo:

 grep 'data=[a-z,0-9,\"]' file

Muitos hits

 grep 'data=[a-z,0-9,\"]+' file

Sem hits

    
por Martin KS 10.10.2016 / 14:21

3 respostas

14

Se você quiser que + signifique "um ou mais dos átomos anteriores", você terá que fazer um dos seguintes:

  1. Use -E (expressões regulares estendidas) (ou -P , PCRE):

    grep -E 'data=[a-z,0-9,\"]+' file
    
  2. Escape + para que seja tratado especialmente nas Expressões regulares básicas usadas por padrão em grep :

    grep 'data=[a-z,0-9,"]\+' file
    
por muru 10.10.2016 / 14:25
9

Pontos:

  • + é um token ERE (Extended Regular Expression), que indica um ou mais token precedente, pode ser usado se a opção -E de grep for usada ou com escape (\+ ) no caso de BRE (Basic Regex), ou seja, apenas% regulargrep

  • A classe de caracteres [a-z,0-9,\"] corresponderia a qualquer um dos caracteres entre [a-z] , [0-9] , , ou " . Isso pode não ser o que você quer

  • Normalmente, grep exibe toda a linha, se você deseja exibir apenas a parte correspondente, use a opção -o de grep

Com base no seu exemplo, você pode fazer:

grep -E '\bdata=[a-z0-9"]+\b' file
  • -E ativa o ERE
  • \b corresponde a arestas de string, largura zero
  • data= corresponde a data= literalmente
  • [a-z0-9"] corresponde a qualquer caractere de [a-z] , [0-9] e " . + corresponde ao token anterior uma ou mais vezes

Seu padrão atual até você corrige, sem \b , isso corresponderia a falsos positivos como foo fdata=2322ab , data=12AB e assim por diante.

Exemplo:

% grep -oE '\bdata=[a-z0-9"]+\b' <<<'<div class="node_thumbnail" data-type="file" name="GOPR0036.MP4_frame000001.jpg" data="813334c25191468c9f1c57afc99fde60" aid="133948" rel="/Files/ToolTipView?fileId=813334c25191468c9f1c57afc99fde60&pageNo=1&NoCache=101016083044" rev="topMiddle"'
data="813334c25191468c9f1c57afc99fde60
    
por heemayl 10.10.2016 / 14:25
-1

Outra opção é usar egrep:

egrep 'data=[a-z,0-9,\"]+' file

egrep é empacotado com grep, é apenas um wrapper para grep:

#!/bin/sh
exec grep -E "$@"

isso é bom para uso interativo. No entanto, em scripts eu usaria grep -E .

    
por Steven Penny 11.10.2016 / 13:40