Прежде всего, так как это мой первый пост здесь, я просто хотел бы сказать, что я считаю, что VIM является отличным инструментом, а форум здесь очень полезен для поиска ответов на вопросы, с множеством полезных людей, предоставляющих неоценимая помощь. Я все еще очень плохо знаком с VIM, поэтому почти все, что я узнал об этом, пришло отсюда.
У меня вопрос: я знаю, как перевернуть ВСЕ строки в файле (: g / ^ / m0 среди других способов), но есть ли способ отменить каждые 4 строки в файле, чтобы
line1
line2
line3
line4
line5
line6
line7
line8
...
становится
line4
line3
line2
line1
line8
line7
line6
line5
...
Вы можете предположить, что в таких файлах всегда будет точное кратное 4 строкам.
Ответы:
Для этого можно использовать команду,
:Reverse
описанную в Vim Wiki (вы можете включить ее в свою,.vimrc
чтобы сделать ее постоянной):Затем вы можете записать макрос для запуска команды через каждые четыре строки:
Объяснение:
qm
: «q» в обычном режиме запускает (и останавливает) запись макроса в заданном регистре (регистр «m», в данном случае, но это может быть любая другая буква)V
: войдите в визуальный режим и выберите текущую строку3j
: расширить визуальный выбор до следующих 3 строк:Reverse<cr>
: выполнить команду Reverse на выбранных строках (<cr>
здесь обозначает enterключ)4j
: перейти к следующим неизменным строкамq
: останавливает запись макроса1000@m
: запустить макрос, записанный в регистре 'm' 1000 раз (вы можете увеличить это число, если ваш файл больше 4000 строк)Редактировать:
Как упоминалось в комментариях, вы можете использовать рекурсивный макрос вместо счетчика:
qM
: если регистр, указанный дляq
заглавных букв, макрос добавляется в регистр (что также полезно, когда вы понимаете, когда пропустили последние шаги в сложном макросе)@m
: запустить макрос в реестреm
q
: перестать добавлять макросНесмотря на то, что он создан как макрос, вы можете создать команду для этого, если это обычная задача в вашем рабочем процессе:
function! Reverse4()
/endfunction
: определяет новую функциюlet reg_m = @m
: сохраняет текущее содержимое реестраm
let @m = "<c-r><c-r>m"
: вставьте макрос в регистрm
- обратите внимание, что<c-r>
это обозначение vim для Ctrl+ rи что вы должны ввести это, а не копировать / вставить, чтобы ваша строка была похожаlet @m = 'V3j:Reverse^M4j@m'
и содержала специальный символ (^ M)normal! @m
: нормальная команда запускает свой аргумент, как это было набрано в обычном режиме, поэтому она запускает рекурсивный макросlet @m = reg_m
: восстанавливает содержимое регистраm
, поэтому вам не нужно помнить, что этот регистр используется в этой функции, и избегать его использованияcommand! Reverse4 call Reverse4()
: создать новую команду для этой функцииВ зависимости от ваших потребностей вы можете улучшить его, например: передать аргумент команде и функции, чтобы он работал для любого количества строк, а не фиксировался в группах по 4 строки.
источник
1000@q
хака, вы можете также использовать рекурсивный макрос:qmqqm ... @mq@m
.command! -bar -range=% Reverse <line1>,<line2>g/^/m<line1>-1|nohl
где-нибудь в вашем vimrc.Как и во всех повторяющихся действиях , если вы можете сделать что-то один раз с основными операциями редактирования, то вы можете легко сделать это много раз, записав макрос.
(В этом случае я буду использовать рекурсивный макрос, но вы можете просто записать нерекурсивный макрос и воспроизвести его несколько раз, нажимая
@@
или используя счетчик.)Сломан
gg
: Перейти к началу файла.qqq
: Очистить регистрq
. Мы увидим, почему это необходимо на шаге 5.qq
: Начать запись макроса для регистрации qddjjpkddkkPjddpjj
: Серия операций, которая переупорядочивает первые четыре строки, просто удаляя и вставляя их вручную. (Это может показаться сложным на первый взгляд, но не обманывайтесь Это очень простой вещи , которые вы бы узнали в первые 5 минут или так.vimtutor
:j
,k
,dd
,p
,P
)@q
: Вызовите макрос! На этом этапе регистрq
ничего не содержит (потому что мы очистили его на шаге 2), поэтому ничего не произойдет.q
: Остановить запись макроса.@q
Воспроизведите рекурсивный макрос столько раз, сколько необходимо.NB Выше не даст желаемых результатов, если файл содержит количество строк, которые не делятся точно на четыре. Чтобы досрочно остановить макрос, если не осталось четырех строк, нам нужно выполнить команду нормального режима Vim, которая потерпит неудачу, прежде чем мы начнем применять изменения в шаге 4. Мы можем сделать это, пытаясь двигаться вниз линию три раза (и затем обратно), прежде чем мы начнем перемещать линии:
jjj3k
Таким образом:
источник
q
он должен быть пустым, иначе он испортит ваши издания.qqqggqqjjjkddkkPjddjpkddkkPjjjj@qq@q
where I can just use the one-line custom command each time I need to do this
- обратите внимание, что вам не нужно пересоздавать макрос каждый раз, когда вам нужно его использовать, так как его можно сохранить как функцию / команду в вашем vimrc.Вы также можете сделать это с помощью
Ex
команды, использующейsed
в качестве внешнего фильтра:Эта версия будет игнорировать (удалять) любые дополнительные строки, превышающие число, кратное 4. Чтобы сохранить последний набор из менее чем 4 строк (обратный), используйте:
%
Здесь означает «Каждую строку в буфере.»Команда
!
означает «Выполнить следующую команду с указанными строками в качестве ввода и заменить указанные строки выводом команды». (Это называется фильтром; очень удобно для таких вещей, как сортировка, например,:%!sort
сортировка всех строк в вашем файле;:2,8!sort
сортировка строк 2-8 и т. Д.)sed
является редактором потоков и доступен во всех Unix-подобных системах. Ключевыми понятиями,sed
используемыми здесь, являются «пространство образца» (которое по умолчанию просто содержит каждую строку ввода по очереди) и «пространство удержания» (где вы можете вставить дополнительный текст при использовании,sed
чтобы сохранить его при обработке других строки ввода).-n
является опцией дляsed
команды, чтобы подавить ее действия по умолчанию печати пространства образца (потому что в этом случае мы хотим печатать, только когда мы явно говорим так).$p
вsed
команде означает «Если вы находитесь на последней строкеsed
ввода, напечатайте (пробел)».h
означает «вставить текущее содержимое« пространства образца »в« пространство удержания », перезаписывая все, что там есть».n
означает «заменить содержимое« пространства образца »следующей строкой из ввода».G
означает «добавить к« пробелу »: символ новой строки, за которым следует содержание« пробела »».Взятые вместе,
sed
команда запоминает четыре строки вывода, обращая их вспять по мере их сохранения, а затем печатает их. Эти$p
команды , добавленные во второй версии убедиться , что если последняя строка файла достигается за исключением на кратному 4 линии, линии по - прежнему печатаются.Для альтернативного, интерактивного подхода, все еще без использования специфических для Vim функций, а также без использования внешнего фильтра:
перейти на четвертую линию.
чтобы повернуть предыдущие четыре строки (1-4) и оставить курсор на строке 8.
.m -4
перемещает текущую строку сразу после строки на четыре строки назад (оставляя курсор на перемещенной строке).+3m .
перемещает строку, которая находится на 3 строки после текущей строки, сразу после текущей строки, оставляя курсор на перемещенной строке.+2m .
конечно работает так же.+5
помещает курсор на пять строк вниз от того места, где он находится.Повторите по желанию.
В Vim вы можете повторить всю эту команду с помощью
@:
, а затем повторите с@@
. В POSIXvi
илиex
вам нужно будет вставить:.m -4 | +3m . | +2m . | +5
в виде строки текста, удалить его в именованный буфер (регистр), а затем выполнить этот именованный буфер (регистр).Таким образом, в
ex
режиме, реверсирование строк в интерактивном режиме с использованием только указанных в POSIX функций и начало с 17 строк текста:Дальнейшее чтение:
ex
vi
источник
4G:.m -4 | +3m . | +2m . | +5<Enter>@:
пор,@@
пока ваш файл не будет полностью обработан. Я рекомендую установить MobaXterm, хотя. :)Простой английский: для каждой строки перемещайте текущую строку вверх
lnum % 4
, если толькоlnum % 4 == 0
в этом случае не перемещайте текущую строку вверх4
.Кроме того, чтобы инвертировать все
n
строки, замените4
's' в приведенной выше команде наn
.источник