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



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



перед:



aaa
bbb
ccc
ddd
eee
fff


после:



aaa
ccc
eee
586   12  
vim

12 ответов:

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

  • запуск в командном режиме.
  • перейдите к началу файла, нажав gg.
  • пресс qq.
  • нажмите стрелку вниз и нажмите dd после.
  • пресс q.
  • пресс 10000@q

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

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

:g/^/+d

можно использовать :normal или :norm для выполнения заданных команд нормального режима. источник.

:%norm jdd
:map ^o ddj^o
^o

здесь ^ обозначает CTRL. Рекурсивный макрос для удаления строки каждые две строки. Выберете первую строку и готово.

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

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

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

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

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

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

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

как вариант

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

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

вы должны быть в состоянии использовать макрос:

http://www.oreillynet.com/mac/blog/2006/07/more_vim_save_time_with_macros_1.html

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

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

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

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

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

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

это, вероятно, не "vim путь", но может быть проще запомнить, если вы знаете питон.

для удаления нечетных строк (1,3,5,..) ->:%s/\(.*\)\n\(.*\)\n/\r/g

для удаления четных строк (2,4,6,..) ->:%s/\(.*\)\n.*\n/\r/g

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

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

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

Comments

    Ничего не найдено.