Удалять все, кроме нескольких строк, через несколько файлов

У меня есть целая куча файлов с определенными шаблонами

ABCD: Something 1 Anything 2 EFGH: Something 3 Anything 4 ABCD: Something 5 Anything 6 HIJK: Something 7 Anything 8 

Я хочу сохранить вторую строку после ABCD и удалить все остальное во всех этих файлах. В одном файле это можно сделать с помощью vim следующими командами

 /ABCD\_[^a-zA-Z] (*searches the pattern*) qaq (*flush register*) :g//norm! "A3Y (*yank 3 lines including pattern into register A*) ggVG"ap (*delete everything else*) 

Затем я могу выполнить несколько простых поисков регулярных выражений, чтобы удалить ABCD и Somethings, чтобы они остались с правильными Anythings.

Однако использование args и argdo предложенных здесь для нескольких файлов, вызывает вторую ошибку «Не команда редактора» во второй операции выше. То же самое происходит, если я обойду второй, и перейду прямо к третьему и четвертому. Я выполняю args и argdo после каждого шага.

Любые рекомендации, остающиеся в пределах или выходящие за пределы vim?

Попробуйте сделать все это одним гигантским normal! команда:

 :argdo norm! /ABCD\_[^a-zA-Z]<Cv><CR>qaq:g//norm! "A3Y<Cv><CR>ggVG"ap 

Использование <Cv><cr> позволяет ввести литеральный возврат каретки. Это устраняет вашу проблему, но в вашем подходе все еще есть много вещей, которые не идеальны.

Например:

  • Нет необходимости искать что-то, а затем использовать :g// . Вместо этого просто используйте :g/ABCD\_[^a-zA-Z] .

  • Вы можете использовать \_A вместо \_[^a-zA-Z]

  • Нет необходимости, чтобы глобальная команда выполняла обычную команду. Вместо этого выполните команду ex, и вам не нужно очищать регистр «a». Так же :g/ABCD\_A/3ay .

Объединив все это, я бы рекомендовал

 :argdo norm! :g/ABCD\_A/3ya<Cv><CR>ggVG"ap 

Поскольку вы также ищете ответ с помощью awk :

 awk '/ABCD/ {getline; getline; print}' input