Я столкнулся с поведением, которое не могу объяснить. Надеюсь, кто-то из вас сможет мне помочь.
Я пытаюсь создать своего рода документацию по более крупному Ant
проекту, которую я использую sed
для фильтрации информации из файлов, которая мне позже понадобится в документации.
У меня есть обычный файл сборки Ant со строками вроде этих:
<target name="targetA" depends="targetD" description="some fancy description">
...
<target name="targetB" depends="targetD" description="some fancy description">
...
<target name="targetC" depends="targetD" description="some fancy description">
Теперь я запускаю эту строку sed:
sed -nr 's/.*?target name="(.*?)".*="(.*?)".*/ * \1 - \2/p'
Это должно дать мне:
* targetA - some fancy description
* targetB - some fancy description
* targetC - some fancy description
Вместо этого я получаю:
* targetA" depends="targetD" - some fancy description
* targetA" depends="targetD" - some fancy description
* targetA" depends="targetD" - some fancy description
Я попробовал пропустить вывод второй группы, чтобы убедиться, что именно первая группа на самом деле соответствует всей части «depends», хотя я установил регулярное выражение нежадным до следующей двойной кавычки.
Что я здесь упускаю?
Использование более явного регулярного выражения, подобного этому, работает так, как и ожидалось, но я все еще не понимаю, в чем суть жадности:
sed -nr 's/.*?target name="(.*?)".*=.*="(.*?)".*/ * \1 - \2/p'
Поскольку это может быть интересно, я использую sed-4.2.2-4ubuntu1 на Ubuntu Linux (установка по умолчанию)
решение1
Sed не поддерживает нежадные совпадения, как в выражении «.*?».
Попробуй это:
sed -nr 's/.*target name="([^"]*)" .*="(.*)".*/ * \1 - \2/p' file
Выход:
* targetA - какое-то причудливое описание * targetB - какое-то причудливое описание * targetC - какое-то замысловатое описание