这是这个问题的延伸(我之前曾问过):
How to delete every other row, plus paste deleted results after selection?
,但现在我想推广到n条纹数据
因此,这个问题的扩展将是如何将此概括为无条带数据集?
显然,上面的内容实际上是每排其他行的2行,但是如果我们想要在下面这种模式中有效地对数据进行排序,那么对于3行的排序是什么? N排destripe?
在:
111
222
333
444
555
666
NEW AFTER(如果使用2条纹):
111
333
555
222
444
666
NEW AFTER(3条纹如下图所示):
111
444
222
555
333
666
可能有一个算法名称;我没有强大的分类背景,但可能有一个名字 - 如果有人可以澄清请通知我。
同样,带参数的宏(或不是)是我在这里尝试解决的问题。这在排序实用程序空间中也可能有效,但基于前一个问题的答案,我认为它在vimscript中是可行的。
那么我想为脚本制作的东西就像(在数据上做一个视觉线选择),然后调用像
这样的用户宏函数:'<','>' call Destripe(2)
:'<','>' call Destripe(3)
其中单个参数描述了条带化。
另一个例子(我想要做的更清楚),如果我有3条数据
BEFORE(LHS)&amp;之后(RHS):
aaa aaa
bbb aaa
ccc aaa
aaa bbb
bbb bbb
ccc bbb
aaa ccc
bbb ccc
ccc ccc
带有2条纹数据的示例
BEFORE(LHS)&amp;之后(RHS):
aaa aaa
bbb aaa
aaa aaa
bbb bbb
aaa bbb
bbb bbb
感谢@lornix的想法
答案 0 :(得分:2)
"
function! Destripe(stripe) range
call setpos('.',[0,a:firstline,1,0])
let numlines=(a:lastline-a:firstline+1)/a:stripe
let currentline=a:firstline+a:stripe-1
while numlines > 0
call setpos('.',[0,currentline,1,0])
let currentline=currentline+a:stripe-1
silent :.m$
let numlines=numlines-1
endwhile
endfunction
"
%call Destripe(2)
在111,222,333 ...行列表中获取上述内容,给出以下内容:(加倍以节省空间)
111 111
222 333
333 555
444 777
555 999
666 222
777 444
888 666
999 888
我担心3及更高版本可能无法生成您正在寻找的内容,因为您没有指定从文件的CURRENT(移位)内容或文件的ORIGINAL内容中读取内容。 (这有意义吗?)
如上所述,它需要提供一个范围,'%'或'&lt;,'&gt;或行#。
答案 1 :(得分:2)
说实话,如果这不是必须要做的事情 经常,或者如果没有太多的条纹, 我只需在命令行键入以下内容 (三条纹)。也许你可以看到这是怎么回事 可以概括。
:let @a = '' | let @b = ''
:g/^/ +d A | d B
:put a | put b
答案 2 :(得分:0)
function! Destripe(stripe) range
let s:rowbeg=getpos("'<")[1]
let s:rowend=getpos("'>")[1]
let s:curSetLngth=s:rowend-s:rowbeg+1
let stripe=a:stripe
let s:rowend += 1
while stripe >= 2
let stripeMin1 = stripe - 1
" clear register
let @e=''
" delete last stripe and append
" to the e register
execute "let @a='".stripeMin1."j\"Edd'"
" count how many times to perform a-macro
let s:stripesInSlctn = s:curSetLngth / stripe
"silent ":'<"
let s:count=0
while s:count <= s:stripesInSlctn
norm @a
let s:count = s:count + 1
"dbg echo s:count s:stripesInSlctn s:curSetLngth stripe s:rowbeg s:rowend
endwhile
let s:curSetLngth -= s:stripesInSlctn + 1
" rowend location
let s:rowend -= s:count
execute s:rowend
" e-register collected the stripes
" so place at bottom of selection
norm "ep
execute s:rowbeg
let stripe -= 1
let s:stripesInSlctn -= 1
endwhile
endfunction
如果有办法清理它,请告诉我;例如,它仅适用于视觉线选择,因为我设置了脚本。
要从命令行调用,请选择可视行,然后
:'<,'> call Destripe(n)
其中n是条纹数。
脚本有效执行以下操作 BEFORE(LHS)&amp;之后(RHS):
aaa aaa
bbb aaa
ccc aaa
aaa
bbb bbb
ccc bbb
aaa bbb
bbb
ccc ccc
ccc
ccc
解决方案的一个潜在问题是,耗尽结果之间的空白区域始终存在。有人会知道如何调试那个吗?在大多数情况下,这可以完成工作。感谢@lornix的一些灵感(我甚至不知道如何在vim中编写脚本!,我也不知道如何将范围输入函数)。 SO社区如果您对如何改进它有任何意见我会非常感激。
另一个需要考虑的问题是,norm命令可能根本无法使用,因为它在“每一行”的基础上工作,而不是在第n行的基础上工作!所以基本上我希望有一种方法可以在第n行进行操作(在我这里的乘法场景中很有用,或者你对每3行,每4行感兴趣的情况等)也许有一个特点我只是不使用?