Использование vim для удаления всех строк, кроме тех, которые соответствуют произвольному набору строк


6

Я использую vim для удаления всех строк, кроме тех, которые соответствуют определенной строке, например,

: g! / [строка, которую я хочу оставить в редакторе] / d

Работает отлично. Но то, что я действительно хочу и нигде не нашел, это способ использования vim для удаления всего, кроме нескольких строк.

Например, допустим, у меня есть открытый файл со следующей информацией:

Dave came at 12PM
Lucy came at 11AM
Trish came at 5PM
John ate lunch at 2PM
Virgil left at 3PM
Dave left at 6PM

и я хочу, чтобы у меня остались только события, в которых упоминаются Дейв и Джон - какую команду vim я мог бы использовать, чтобы в итоге получить:

Dave came at 12PM
John ate lunch at 2PM
Dave left at 6PM

Я понимаю, что могу использовать инструменты командной строки, такие как findstr в Windows и другие в * nix, но я часто бываю в vim и не смог разобраться с какой-либо командой regex или vim, которая это сделает. Спасибо!

Ответы:


13

:global Команда, на которую вы ссылаетесь в своем вопросе, на самом деле не просто принимает буквенные строки, она обрабатывает любое регулярное выражение. Итак, вам просто нужно придумать тот, который имеет две ветви, один для John и один для Dave, Вуаля:

:g!/Dave\|John/d

Обратите внимание, что этот упрощенный также будет соответствовать Johnny; Вы, вероятно, хотите ограничить матчи целые ключевые слова :

:g!/\<\(Dave\|John\)\>/d

Регулярные выражения являются мощной функцией Vim; стоит узнать о них больше. Начать в :help regular-expression,


1
Боже мой, я забыл сбежать из трубы, когда попробовал это. Я сделаю это сейчас! Спасибо.
Dave

2
Это или использовать \v модификатор «очень волшебный», который позволяет вам опустить большинство обратных слэшей, как в ответе Ливена Кирсмаекера.
Ingo Karkat

Это было это. Я избежал всего в своем регулярном выражении, но каким-то образом упустил из виду трубу. :)
Dave

1
Чтобы сохранить персонажа, вы можете использовать :v вместо :g!,
Kevin

6

Следующие должны это сделать

:v/\v(Dave|John)/d

Сломать

:v                  matches all lines not containing the search expression 
/\vDave|John        search expression
/d                  execute delete on all those lines 

0

Использовать этот:

:%s/^[^Dave|John].*\n//

Имея в виду:

%            means search the whole file
^            at the beginning of the line
[^Dave|John] something that isn't Dave nor John
.*           match anything
\n           new line character
//           replace with nothing

3
Использование :s удалить целые строки более громоздко, чем :g из вопроса. И это [^Dave|John] ерунда
Ingo Karkat
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.