在Vim中重新排序数据

时间:2012-05-01 08:23:15

标签: vim macros rows

我有一个分层列表,就像这样

Menu1,SubMen1.1,SubMen1.2,SubMen1.3
Menu2,SubMen2.1,SubMen2.2,SubMen2.3
Menu3,SubMen3.1,SubMen3.2,SubMen3.3

我想运行一个脚本或宏来重新排列信息到这个

Menu1,SubMen1.1
Menu1,SubMen1.2
Menu1,SubMen1.3
Menu2,SubMen2.1
Menu2,SubMen2.2
Menu2,SubMen2.3
...

我有什么方法可以做到这一点吗?

修改

我应该说所有行都有不同的长度。有些只有一个项目,有些只有八个。

在一个文件中还有大约4,000个。我还有另外20个文件。

2 个答案:

答案 0 :(得分:3)

前几天有一个similar question on redditthe solution posted there by sylvain_soliman似乎也适用于此案例。我在这里张贴它仅仅是为了展示一个解决问题的不同方法。

:%s/\(^\([^,]*\),.\+\)\@<=,/\r\2,/g

为了使其更具可读性,请使用\v

:%s/\v(^([^,]*),.+)@<=,/\r\2,/g

一点解释:

  • :%s/ - 替换缓冲区中的所有行
  • \v - 使用“非常神奇”的正则表达式语法(防止转出像parens这样的东西)
  • (^([^,]*),.+) - 匹配一行开头的字符串,后跟一个逗号,后跟至少一个字符。这会将字符串从行的开头放到matchgroup 2中的逗号。
  • @<= - 告诉vim将前一组与零宽度匹配,因此不会被替换。
  • , - 匹配下一个逗号。
  • /\r\2,/g - 使用换行符和来自matchgroup 2的字符串替换上面的逗号。

答案 1 :(得分:2)

我使用宏来做到这一点,也许不是优雅,但有效。 (<CR>enter密钥)

ggqqdw:s/,/\="\r".getreg('"').','/g<CR>jq

现在您可以使用@q重复宏:

4000@q

最后,删除所有临时空行

:g/^$/d