隔行行vim
回答
这里是一个“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。
编辑:映射的解释。我将在问题中使用示例,就好像它已经运行一次这个映射。
一个运行后:
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
将只是正常交错。有2个参数,它将会指定多少个组合在一起。例如将从顶部取2行,然后从底部取1行进行交织。
我们解决您的问题
:1,/c/-1Interleave
:Interleave 2 1
1,/c/-1
范围内开始的第一行和结束1行匹配信c
第一线之上。:1,/c/-1Interleave
基本上交织的a
组的和b
的- 范围此时整个文件。
- 将
a
和b
的混合组与c
组交错。具有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)? ;) – 2016-02-24 09:02:18
我刚刚在今晚独自遇到了这个问题。我的问题不像一些答案那样优雅,但是我认为它更容易理解。它使许多假设,所以这是一个黑客攻击的一位:
- A)它假定有一些独特的字符(或任意字符 字符串)不存在任何线路的 - 我想下面
@
。 - B)它 假定您不希望在任何 a,b或c节中的前导或尾随空白。
C)它假定可以很容易地识别 最大行长度,然后垫所有线是长度(例如 可能使用%!成AWK或等等,用printf)
- 垫所有具有相同最大长度的空格的行。
- Visual仅选择a和b部分,然后
%s/$/@
- 将块复制并越过b部分以在c部分之前。
- 将块复制并粘贴到bc部分的前面。
%s/@/\r
%s/^ *//g
%s/ *$//g
- 删除线左其中a和b切片。
如果你有xclip
你可以剪切线和使用paste
交织他们:
- 视觉选择一组线
- 类型
"+d
将它们剪切到剪贴板 - 目视选择另一组线
- 类型
!paste -d '\n' /dev/stdin <(xclip -o -selection clipboard)
- 1. 从vim命令行运行vim脚本
- 2. vim行尾
- 3. 执行Vim
- 4. Vim正则表达式每隔几行添加大括号
- 5. 在Vim中换行
- 6. Vim粘贴行为
- 7. Vim自动换行
- 8. Vim:分词成行?
- 9. 隔离行
- 10. Vim 7.4已安装,但在运行时执行Vim 7.3
- 11. 代码和行号之间的Vim行
- 12. vim:用no行代替行模式
- 13. 自动换行VIM中的长行
- 14. 通过命令行运行vim与在vim编辑器中运行vim的区别
- 15. Java CSV行分隔
- 16. RTF行分隔符
- 17. Vim,TextMate,git和换行
- 18. Vim:执行当前文件?
- 19. 在Vim中移动行
- 20. Vim多行搜索模式
- 21. Vim:用字符填充行
- 22. Vim:找到下一行
- 23. Vim自动缩进换行
- 24. Vim的,长行和滚动
- 25. 从cmd运行make vim
- 26. 在vim上运行python
- 27. Vim - 奇怪的行为
- 28. Vim:替换行的末尾
- 29. Vim中的多行高亮
- 30. Vim全局替换(行)
这是真实世界的情况还是减少的测试用例? – romainl 2013-02-10 07:23:27
减少测试用例。有三组需要隔行扫描,但每个组合需要更长的时间。我可以对一个宏,但我认为可能有一个更好的方法:g和移动 – jpiasetz 2013-02-10 07:29:48
嗯,如果所有'a's是相同的和'b's是相同的和'c's是相同的我' d只需手动命令第一个'abc'(':/ b/m。',':/ c/m.')并将结果块复制3次(这很快),但是您的真实世界需求可能更复杂。 – romainl 2013-02-10 07:43:44