key\s*=\s*.+
é a sintaxe GNU ERE (supondo que você queira que \s
corresponda a qualquer caractere de espaçamento e +
para corresponder a um ou mais dos átomos anteriores), então você precisaria da implementação GNU de grep
e passar -E
opção.
No entanto, mesmo assim, não faria muito sentido
Primeiro
grep 'key\s*=\s*.+'
é funcionalmente equivalente a
grep 'key\s*=\s*.'
Porque, se uma string corresponder a anything.+
, ela também corresponderá a anything.
e vice-versa.
Além disso, um caractere de espaçamento também é um caractere. Como \s*
corresponde a 0 ou mais caracteres de espaçamento, key\s*=\s*.
é funcionalmente equivalente a key\s*=.
(linhas que contêm key<optional-spaces>=<one-character-space-or-not>
).
Aqui você quer:
grep 'key\s*=\s*\S'
para pedir pelo menos um caractere sem espaçamento a ser encontrado à direita do =
, que é funcionalmente equivalente a:
grep 'key\s*=.*\S'
Observe que ele corresponde a key = foo
, mas também nonkey = foo
. Se você quiser que o key
seja encontrado apenas no início da linha, será necessário solicitá-lo com o ^
anchor:
grep '^key\s*=.*\S'
Ou use -x
para o regexp corresponder à linha inteira:
grep -x 'key\s*=.*\S.*'
Observe que o equivalente padrão de \s
é [[:space:]]
( [^[:space:]]
para \S
).
Outra maneira de abordar o requisito seria usar operadores estendidos encontrados em alguns regexps, como os PCRE, para evitar o back-tracking.
key=\s*.
corresponde a key=
porque o mecanismo regexp tem \s*
avidamente pelos caracteres de espaço após o =
, localiza 1 e, em seguida, percebe que não pode corresponder ao .
ao atingir o final de a linha e, em seguida, rastreia para tentar com menos correspondências de \s
(0 nesse caso) para que o próximo .
possa corresponder (aqui um caractere de espaço).
Com o PCRE, como quando usamos a opção -P
com o GNU grep
, você pode escrever:
grep -P '^key\s*=(?>\s*).'
Essa sintaxe (?>...)
impede o rastreamento de retorno. Portanto, o \s*
irá consumir o maior número possível de caracteres de espaçamento, sem poder retroceder, portanto, somente coincidirá se houver pelo menos um caractere sem espaçamento após os espaços.
$ printf 'key=%s\n' '' ' ' ' a' | grep '^key\s*=\s*.'
key=
key= a
$ printf 'key=%s\n' '' ' ' ' a' | grep -P '^key\s*=(?>\s*).'
key= a
$ printf 'key=%s\n' '' ' ' ' a' | grep '^key\s*=.*\S'
key= a