На це питання вже є відповідь тут:
У Vim мені часто здається, що мене цікавлять лише рядки, що містять певний рядок тексту, і хочу видалити всі інші рядки.
Зрівняти рядки, що містять рядок, легко:
:s/^.*foo.*\n//
Зазвичай я роблю два проходи, один, щоб "позначити" всі потрібні рядки спеціальним першим символом:
:s/^\(.*foo.*\)$/X\1/
А у другому проході легко виконати негативну відповідність одному символу у фіксованій позиції, тому я видаляю всі рядки без рядка таким чином:
:s/^[^X].*\n//
Але чи не існує набагато простішого способу зробити це лише одним проходом? Що я пропускаю?