3

У меня странная проблема с grep (2.12-2, тестирование Debian).

В некоторых ситуациях, когда я делаю что-то вроде этого:grep -rni '."spacer">.' . grep верните мне несколько пустых строк:

Если я добавлю --color=none все строки станут видимыми.

Опции grep в .bashrc:

export GREP_COLORS='fn=01;34:ms=01;33:ln=33'
alias grep='grep --color=auto'

1 ответ1

6

Очень полезным инструментом для отладки такого рода вещей является 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">

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .