Очень полезным инструментом для отладки такого рода вещей является od . Передача вывода вашей команды grep через od показала, что ваш файл содержит окончания строк в стиле DOS, возврат каретки (\r), за которым следует новая строка (\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
Итак, для тестирования я создал этот минимальный тестовый файл:
$ echo -ne "<div class=\"spacer\">\r\n<div class=\"spacer\">\r\n" > foo.php
$ cat foo.php
<div class="spacer">
<div class="spacer">
Я подтвердил, что grep печатает пустые строки:
$ grep -i '."spacer">.' foo.php
$
Причиной печати пустых строк является возврат каретки (\r). Вы просите, чтобы grep нашел пробел строки spacer"> и следующий символ. В вашем файле следующий символ - \r . Печать \r в терминале приводит к очистке последней напечатанной строки, в результате чего отображается пустая строка. Вы можете проверить это с помощью следующей команды:
$ echo -e "foo\rbar"
bar
На самом деле происходит то, что сначала печатается foo , затем удаляется из-за \r и заменяется на bar . Проверьте с od:
$ echo -e "foo\rbar" | od -c
0000000 f o o \r b a r \n
0000010
Теперь я не понимаю, почему colors опция grep меняет положение вещей. Это должно быть связано с тем, как отображаются специальные символы. В любом случае вы можете решить вашу проблему, удалив все \r:
$ sed 's/\r//g' default.php > bar.php
Затем удалите последний . из вашего шаблона grep (помните, что по умолчанию . не соответствует символам новой строки, хотя он соответствует \r):
$ grep -ni '."spacer">' bar.php
103: <div class="spacer">
222: <div class="spacer">