Vim: как удалить каждую вторую строку?

Как это сделать в Vim:

ДО:

aaa
bbb
ccc
ddd
eee
fff

ПОСЛЕ:

aaa
ccc
eee

Ответ 1

Для этого можно использовать макрос. Выполните следующие действия.

  • Начало в командном режиме.
  • Перейдите в начало файла, нажав gg.
  • Нажмите qq.
  • Нажмите стрелку вниз и нажмите dd после.
  • Нажмите q.
  • Нажмите [email protected]

PS: Чтобы перейти в командный режим, просто нажмите Escape пару раз.

Ответ 2

Элегантный (и эффективный) способ решения этой задачи - :+delete команда удаления строки рядом с текущей, на каждой строке используя команду :global.

:g/^/+d

Ответ 4

:map ^o ddj^o
^o

Здесь обозначается CTRL. Рекурсивный макрос для удаления строки каждые две строки. Хорошо выбирайте свою первую линию, и это сделано.

Ответ 5

из почтовый архив vim:

:let i=1 | while i <= line('$') | if (i % 2) | exe i . "delete" | endif | let i += 1 | endwhile

(Чтобы быть введенным в одной строке в командной строке vim, будет удаляться строка 1,3,5,7,...)

Ответ 6

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

:%!perl -nle 'print if $. % 2'

(или используйте "если" вместо "если", в зависимости от того, какие строки вы хотите)

Ответ 7

:%!awk -- '++c\%2'

в качестве альтернативы

:%!awk -- 'c++\%2'

в зависимости от того, какую половину вы хотите вырезать.

Ответ 9

В качестве другого подхода вы также можете использовать python, если ваш vim поддерживает его.

:py import vim; cb = vim.current.buffer; b = cb[:]; cb[:] = b[::2]

b = cb[:] временно копирует все строки в текущем буфере в b. b[::2] получает каждую вторую строку из буфера и присваивает ей весь текущий буфер cb[:]. Копия для b необходима, поскольку объекты буфера, похоже, не поддерживают расширенный синтаксис среза.

Это, вероятно, не "vim way", но может быть легче запомнить, если вы знаете python.

Ответ 10

Вы можете использовать собственные возможности поиска и замены Vim следующим образом: Поместите курсор в первую строку и введите обычный режим:

:.,/fff/s/\n.*\(\n.*\)/\1/g
  • .,/fff/ - это диапазон для подстановки. Это означает "от этой строки до строки, которая соответствует регулярному выражению fff (в данном случае, последней строке).
  • s/// является заменой команды. Он ищет регулярное выражение и заменяет каждое его появление строкой. g в конце означает повторение замещения до тех пор, пока регулярное выражение не будет найдено.
  • Регулярное выражение \n.*\(\n.*\) соответствует новой строке, затем целая строка (.* соответствует любому количеству символов, кроме новой строки), затем еще одна строка новой строки и другая строка. Скобки \( и \) заставляют запись внутри них записываться, поэтому мы можем использовать ее позже, используя \1.
  • \1 вставляет сгруппированную новую строку и строку после нее, потому что мы не хотим, чтобы следующая строка тоже ушла - мы просто хотим, чтобы механизм замещения проходил мимо нее, поэтому мы не удаляем ее в следующей замене.

Таким образом вы можете управлять диапазоном, в котором хотите удалить, и вам не нужно использовать какой-либо внешний инструмент.

Ответ 11

Чтобы удалить нечетные строки (1,3,5,..) → :%s/\(.*\)\n\(.*\)\n/\2\r/g

Чтобы удалить четные строки (2,4,6,..) → :%s/\(.*\)\n.*\n/\1\r/g

Искать текст (формирует первую строку), за которым следует новый символ строки и еще один текст (формирует вторую строку), за которым следует еще один новый символ линии, и заменяйте выше либо первое совпадение (нечетная строка), либо второе совпадение ( ровная линия), а затем возврат каретки.

Ответ 12

вы можете попробовать это в vim

:2,$-1g/^/+1d