Я пытаюсь чередовать три группы строк текста. Например идут отПереплетение строк vim
a
a
a
b
b
b
c
c
c
Для
a
b
c
a
b
c
a
b
c
Есть эффективный способ сделать это?
Я пытаюсь чередовать три группы строк текста. Например идут отПереплетение строк vim
a
a
a
b
b
b
c
c
c
Для
a
b
c
a
b
c
a
b
c
Есть эффективный способ сделать это?
Вот «Oneliner» (почти), но вы должны повторить это для каждой уникальной линии минус 1, в вашем примере 2 раза. Возможно, бесполезно, но я думаю, что это было хорошее упражнение, чтобы больше узнать о шаблонах в VIM. Он обрабатывает все виды строк, пока целая линия уникальна (например, mno
и mnp
- две уникальные строки).
Сначала убедитесь, что это (и сделать не уже /
отображаются на что-нибудь, или что-нибудь еще в линии):
:set nowrapscan
Затем карту, например, эти (должны быть рекурсивными, неnnoremap
):
<C-R>
и <CR>
должны быть набраны буквально.
\v
в шаблонах означает «очень магия», @!
отрицательный взгляд вперед. \2
используйте то, что найдено во второй круглой скобке.
:nmap ,. "xy$/\v^<C-R>x$<CR>:/\v^(<C-R>x)@!(.*)$\n(\2)$/m-<CR>j,.
:nmap ,, gg,.
Затем сделайте ,,
столько раз, сколько это занимает, в вашем примере 2 раза. Один для всех b
s и один для всех c
s.
EDIT: объяснение отображения. Я буду использовать пример в вопросе, как если бы он работал один раз с этим сопоставлением.
После одного запуска:
1. a
2. b
3. a
4. b
5. a
6. b
7. c
8. c
9. c
Курсор затем на последней a
(строка 5), при вводе ,,
, это первый вернуться к первой линии, а затем запускает отображение для ,.
, и что отображение делает это:
"xy$ # yanks current line (line 1) to reg. "x" ("a") "
/\v^<C-R>x$<CR> # finds next line matching reg. "x" ("a" at line 3)
:/\v^(<C-R>x)@!(.*)$\n(\2)$/m-<CR>
# finds next line that have a copy under it ("c" in line 7) and moves that line
# to current line (to line 3, if no "-" #after "m" it's pasted after current line)
# Parts in the pattern:
- ^(<C-R>x)@!(.*)$ # matches next line that don't start with what's in reg. "x"
- \n(\2)$ # ...and followed by newline and same line again ("c\nc")
- m-<CR> # inserts found line at current line (line 3)
j # down one line (to line 4, where second "a" now is)
,. # does all again (recursive), this time finding "c" in line 8
...
,. # gives error since there are no more repeated lines,
# and the "looping" breaks.
Где-то в глубине моих ~/.vim
файлов У меня есть команда :Interleave
(добавлено ниже). Без аргументов :Interleave
будет просто чередовать как обычно. С двумя аргументами, как он будет указывать, сколько из них должно быть сгруппировано. например :Interleave 2 1
займет 2 строки сверху, а затем чередуется с 1 рядом со дном.
Теперь, чтобы решить вашу проблему
:1,/c/-1Interleave
:Interleave 2 1
1,/c/-1
диапазон, начиная с первой строки и заканчивая 1 строку выше первой линии, соответствующей письмо c
.:1,/c/-1Interleave
в основном чередовать группы a
-х и b
's:Interleave 2 1
диапазон весь файл на этот раз.:Interleave 2 1
interleave группа смешанных a
и b
с группой c
s. Со смесями от 2 до 1.Код :Interleave
приведен ниже.
command! -bar -nargs=* -range=% Interleave :<line1>,<line2>call Interleave(<f-args>)
fun! Interleave(...) range
if a:0 == 0
let x = 1
let y = 1
elseif a:0 == 1
let x = a:1
let y = a:1
elseif a:0 == 2
let x = a:1
let y = a:2
elseif a:0 > 2
echohl WarningMsg
echo "Argument Error: can have at most 2 arguments"
echohl None
return
endif
let i = a:firstline + x - 1
let total = a:lastline - a:firstline + 1
let j = total/(x + y) * x + a:firstline
while j < a:lastline
let range = y > 1 ? j . ',' . (j+y) : j
silent exe range . 'move ' . i
let i += y + x
let j += y
endwhile
endfun
Интересный [сшивка] (http://vi.stackexchange.com/a/4576/2978)? ;) –
Я просто столкнулся с этим вопросом сегодня вечером. Мое не так изящно, как некоторые из ответов, но это легче понять, я думаю. Это делает много предположений, так это немного рубить:
@
ниже.C) Предполагается, что вы можете легко определить максимальную длину строки , а затем колодки все линии, чтобы быть, что длина (например, возможно с помощью%! В AWK или т.п., используя Printf)
%s/$/@
%s/@/\r
%s/^ *//g
%s/ *$//g
Если у вас есть xclip
вы можете вырезать линии и использовать paste
чередовать их:
"+d
, чтобы сократить их в буфер обмена!paste -d '\n' /dev/stdin <(xclip -o -selection clipboard)
Это реальная ситуация в мире или уменьшенный тестовый пример? – romainl
Уменьшенный тестовый чехол. Есть три группы, которые должны быть чересстрочными, но их более 3-х предметов. Я мог бы изменить макрос, но я думал, что может быть лучший способ: g и move – jpiasetz
Хмм, если все 'a' одинаковы, а 'b' одинаковы, а 'c' одинаковы ' d просто закажите первый 'abc' вручную (':/b/m.',':/c/m.') и дублировать полученный блок 3 раза (что довольно быстро), но ваши потребности в реальном мире, вероятно, более сложны. – romainl