2014-11-05 6 views
1

Я пытаюсь понять поведение SED WRT это регулярное выражение:
sed -n "s/.*Directory \([^>]*\)>/\1/p" /etc/apache2/sites-enabled/*Weird СЕПГ жадный регулярное выражение поведение

Целью здесь является указать путь к корневой директории всех включенных виртуальных хостов в Apache2.

Странная вещь, что результат этой команды образца:
sed -n "s/.*Directory \([^>]*\)>/\1/p" <<< "<Directory /var/www/my_site>", как и ожидалось: /var/www/my_site

Но результат sed -n "s/.*Directory \([^>]*\)/\1/p" <<< "<Directory /var/www/my_site>" является: /var/www/my_site>

Я знаю, что разница является наличие от >. Вопрос в том, почему необходимо добавить > для получения правильного вывода? [^>]* должен быть в состоянии соответствовать всем и останавливаться на >, не фиксируя его в круглых скобках.

Я не понимаю, почему символ '>' попадает в первую команду, а не во вторую. [^>] должен исключил «>» из захватывающих скобок ...

+0

1-я команда имеет '>' в поисковом выражении, а у 2-го ее нет. – anubhava

+1

Я это знаю. Вопрос в том, почему необходимо добавить '>' для получения правильного вывода? '[^>] *' должен иметь возможность сопоставлять все и останавливаться на '>', таким образом, не фиксируя его в круглых скобках. – mak

+0

Вы не соответствуете '>' во второй команде, поэтому она не входит в замену и остается неизменной. Вы заменяете '([^>] * \)' на себя, остальная часть строки остается неизменной.Если вы просто хотите, чтобы в скобках добавить '. *' До конца команды вне скобок. –

ответ

2

в первой строке, заменить всей строки вещей в вашем group1: так что вы получили: /вар/WWW/my_site

в вашей 2-й линии, заменить <Directory......siteNote, а не вся строка, окончание > не было с той же группой захвата. но окончание > оставалось нетронутым. Таким образом, вы видите его на выходе.

другой пример:

$ sed -n "s/fo*\([^o]*\)/\1/p" <<< "foooooowhatever this ooo will leave behind" 
whatever this ooo will leave behind 

В приведенном выше примере, цель заменить это: foooooowhatever this замена является whatever this строка остальное нетронутым.

+0

Делает смысл :) Sed не переписывает '>' (как я попросил с помощью команды s ///), потому что регулярное выражение не будет соответствовать ему, если я не буду явно помещать его в указанное регулярное выражение. – mak

+0

Да, что произойдет, если вы поместили помеченный трюк \\ (\\) и поместили другое соответствующее регулярное выражение вне всех вещей, которые совпадают, просто исчезают, когда вы заменяете и ссылаетесь на помеченный трюк, как \ 1 –

1

1-я команда имеет > в поисковом термине, но 2-й ее не имеет.

[^>]* соответствует всем перед тем> сопоставляется (не включая >), следовательно, > остается в вашей 2-й SED команды, которая:

sed -n "s/.*Directory \([^>]*\)/\1/p" 

Также обратите внимание в первую команду:

sed -n "s/.*Directory \([^>]*\)>/\1/p" 

\1 не улавливает >, но ваша команда sed опускает его на замену.

+1

См. Обновленный ответ, у меня уже есть ответил на ваш комментарий, то есть '[^>] *' соответствует всем, прежде чем '' 'будет найдено в обеих командах. Итак, '\ 1' - это весь текст перед'> '. Только в 1-й команде у вас есть '>', поэтому она не указана в конечном выпуске. – anubhava

+1

Я принимаю ответ Кента, потому что он представил пример, и он на самом деле был яснее моего понимания. Кроме того, у вас почти в три раза больше репутации, чем у него, поэтому, пожалуйста, не сердитесь на меня за то, что он дал ему куки :) – mak

+0

@mak: Не на всех, всегда есть прерогатива OP, чтобы принять любой ответ. – anubhava

Смежные вопросы