Há um núcleo comum de sintaxe de expressão regular, no entanto, existem sabores distintos. Sua expressão parece conter alguns recursos específicos do sabor perl, em particular o uso de asserções complexas lookaround descrevendo o início e o fim do padrão a ser correspondido, enquanto o grep usa uma expressão regular básica (BRE ) sintaxe que suporta apenas um conjunto mais simples dessas correspondências de comprimento zero , como line- ( ^
, $
) e âncoras de palavras ( \>
, \<
).
Você pode ativar o suporte à expressão regular compatível com perl (PCRE) no grep usando a opção de linha de comando -P (embora observe que a página man atualmente a descreve como "experimental"). No seu caso, você provavelmente quer que o switch -o também imprima apenas o padrão de correspondência, ao invés de toda a linha, ou seja,
cat /var/log/dpkg.log | grep 'remove' | grep -oP '(?<=remove)(.*?)(?=:)'
Esteja ciente de que esta expressão pode falhar se encontrar pacotes que não tenham o sufixo: i386, uma vez que ele pode ler adiante para os dois pontos correspondentes na próxima palavra, por exemplo,
echo "2013-09-07 08:31:44 remove cifs-utils 2:5.1-1ubuntu2 <none>" | grep -oP '(?<=remove)(.*?)(?=:)'
cifs-utils 2
Você pode querer olhar para o awk, por exemplo,
cat /var/log/dpkg.log | awk ' ~ /remove/ {sub(":.*", "", ); print }'
Assim como o BRE e o PCRE, o Gnu grep tem um outro modo chamado expressão regular estendida (ERE), especificado pela opção de linha de comando -E. A página man observa que
In GNU grep, there is no difference in available functionality
between basic and extended syntaxes.
No entanto, você deve observar que "nenhuma diferença na funcionalidade disponível" não não significa que a sintaxe é a mesma. Por exemplo, no BRE, o caractere +
é normalmente tratado como literal e só se torna um modificador que significa 'uma ou mais instâncias da expressão regular precedente' se for escapado, ou seja,
$ echo "123.456" | grep '[0-9]+\.[0-9]+'
$ echo "123.456" | grep '[0-9]\+\.[0-9]\+'
123.456
enquanto que para o ERE é exatamente o oposto
$ echo "123.456" | grep -E '[0-9]+\.[0-9]+'
123.456
$ echo "123.456" | grep -E '[0-9]\+\.[0-9]\+'
Uma distinção semelhante se aplica a sed
chamado sem e com a opção -r
.