2

В Vim я часто нахожу, что меня интересуют только строки, содержащие определенную строку текста, и я хочу удалить все остальные строки.

Это легко сопоставить строки, содержащие строку:

:s/^.*foo.*\n//

Обычно я делаю два прохода, один из которых "помечает" все нужные мне строки специальным первым символом:

:s/^\(.*foo.*\)$/X\1/

И во втором проходе легко сделать отрицательное совпадение для одного символа в фиксированной позиции, поэтому я удаляю все строки без моей строки таким образом:

:s/^[^X].*\n//

Но разве не существует более простого способа сделать это всего за один проход? Что мне не хватает?

2 ответа2

9

Это удалит все строки, которые не содержат foo .

:g/^\(.*foo\)\@!.*$/d

Вместо этого вы также можете использовать :v чтобы изменить смысл поиска.

:v/\(foo\)/d

Вы можете прочитать больше о том, как :g и :v работают здесь.

И еще об определении диапазонов, использовании метасимволов и т.д. Для поиска и замены здесь.

0

Что ж, если ваша цель состоит только в удалении строк с текстом, это можно легко сделать с помощью awk следующим образом:

awk '/regex/{print}' filename

Значение awk будет действовать на имя файла. Вы можете передать его по новому имени или тому же имени, например:

   awk '/regex/{print}' filename > filename.tmp && mv filename.tmp filename

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