Uma ferramenta muito útil para depurar esse tipo de coisa é od
. Passar a saída do comando grep
através de od
mostrou que seu arquivo contém terminações de linha no estilo DOS, retorno de carro ( \r
) seguido por uma nova linha ( \n
):
$ grep -i '."spacer">.' default.php | od -c
0000000 \t \t \t \t \t < d i v c l a s s =
0000020 " s p a c e r " > \r \n \t \t \t < d
0000040 i v c l a s s = " s p a c e r
0000060 " > \r \n
0000064
Então, para testar, criei este arquivo de teste mínimo:
$ echo -ne "<div class=\"spacer\">\r\n<div class=\"spacer\">\r\n" > foo.php
$ cat foo.php
<div class="spacer">
<div class="spacer">
Confirmei que grep
imprime linhas vazias:
$ grep -i '."spacer">.' foo.php
$
A razão que está imprimindo linhas vazias é o retorno de carro ( \r
). Você está pedindo para o grep
encontrar a string spacer">
e o caractere seguinte . Em seu arquivo, o caractere a seguir é \r
. Imprimir \r
no terminal tem o efeito de limpar a última linha impressa, resultando na exibição de uma linha vazia. Você pode testar isso com o seguinte comando:
$ echo -e "foo\rbar"
bar
O que realmente acontece é que o primeiro foo
é impresso, depois excluído por causa de \r
e substituído por bar
. Verifique com od
:
$ echo -e "foo\rbar" | od -c
0000000 f o o \r b a r \n
0000010
Agora, não entendo por que a opção colors
de grep
está mudando as coisas. Deve ter algo a ver com a forma como os caracteres especiais são exibidos. Em qualquer caso, você pode corrigir seu problema removendo todos os \r
:
$ sed 's/\r//g' default.php > bar.php
Em seguida, remova o último .
do seu padrão grep (lembre-se que por padrão .
não corresponde a novas linhas, embora corresponda a \r
):
$ grep -ni '."spacer">' bar.php
103: <div class="spacer">
222: <div class="spacer">