前段时间有博友在群里问了一个关于vim排序的问题,因为时间问题一直没帮忙解决,今天时间正好空出来,就帮忙搞了一下。 原文的问题如下:
vimuser 说: 2012年03月1日 于 5:04 下午 (编辑) 今天折腾了一下午,研究vim的排序,看了教程和搜索了一些文档,还是没弄明白,vim的正则表达式跟一般的又不一样,来请教下博主。 |1 | 11 | 111| 1111| |2 | 22 | 222| 2222| 要根据第3个|和第4个|之间的列进行排序该如何写命令呢?
其实之前也只是简单的用过vim的sort命令,没有想过vim是否能完成如此复杂的排序,不过抱着试试看的态度,我看了一下sort的描述(:h :sort),其中一段话如下:
:[range]sor[t][!] [i][u][r][n][x][o] [/{pattern}/] When /{pattern}/ is specified and there is no [r] flag the text matched with {pattern} is skipped, so that you sort on what comes after the match. Instead of the slash any non-letter can be used. For example, to sort on the second comma-separated field: :sort /[^,]*,/
翻译过来就是,sort确实可以指定跳过的字段,也就是说,我们只要能通过正则把
|1 | 11 | |2 | 22 |
这一部分跳过就可以了~~ 这部分的正则表达式是:
|[^|]\+|[^|]\+\s*
所以最终的sort命令如下:
:sort /|[^|]\+|[^|]\+\s*/
原文给的例子不好看效果,我们改成如下的例子:
|1 | 11 | 222| 1111| |2 | 22 | 111| 2222|
调用:sort命令的结果是和原来的样子一致的,而调用我们的新命令的结果是:
|2 | 22 | 111| 2222| |1 | 11 | 222| 1111|
OK,就这样~
依云 on #
Vim 的正则是可以直接指定列位置的,再加上 r 标志,排序多方便~
可惜不支持浮点数。
此例用 sort 命令也很简单。
Reply
yboren on #
如果是linux,也可以调用外部sort命令,:%!sort -t'|' -k3 -r
Reply
wowo on #
求vim的qq群中多少,我要加群,谢谢。求交流学习。
Reply
Dante on #
呃,这个真没有,主要是有群的效果并不是太好。。很多知识沉淀不下来
Reply
赢球之声-live.779a.com|58i9cz on #
文章太好了,仔细看完了,觉得很精彩,支持下,!!!壬辰年(龙)三月初三 2012-3-24
Reply
即时比分-live.779a.cc|z9v3yk on #
文章太好了,仔细看完了,觉得很精彩,支持下,!!!壬辰年(龙)三月初十 2012-3-31
Reply
Dino on #
有点不明白,说的是正则匹配的部分就会被排序忽略,例子中的
:sort /[^,]*,/
这个 * 是贪心匹配,不仅仅匹配第二列
可以用一下的文本实验
sit,Ait,bit
mat,cat,aggressiv
用 /[^,]*,/ 可以看出vim匹配了第一和第二列,所以按照说明应该是根据第三列排序,可是事实上还是根据第二列排序的,
这是为嘛呢 ?
Reply
Dante on #
不包括,的任意个,并且以,结束
匹配没错的。
Reply
bells on #
“:sort /|[^|]\+|[^|]\+\s*/”
其中 "\s" 是指啥呀?
还有就是感觉最后一个"|"没有匹配上?
Reply
waveacme on #
我也觉得,如果要把第3列数据之前的字符做正则匹配的话,似乎应该是这样:
:sort /|[^|]\+|[^|]\+|\s\+/
但是像博主那样弄也能得到正确结果,感觉好神奇。
另外,感谢分享,又学到一招。
Reply
skywalker on #
在vi里help 了一下pattern,第4部分overview of 我觉得
Reply
skywalker on #
在vi里help 了一下pattern,第4部分overview of pattern items,\s代表空白字符,所以\s*应该是任意多个空白字符,我觉得最后一个|其实匹配与否无所谓,就算不跳过这个|,从第三列排序的时候每一个元素开头都是|字符,所以其实还是从|后面的第一个字符开始sort
Reply
bells on #
有道理,谢谢了。
Reply
- on #
博主这里的排序其实还是排除掉无关的部分,对剩下的内容做字符串排序,我非常在意的就是vim能否实现,对指定的部分(利用正则表达式)做指定规则的排序,比如说对第4-8列之间的内容按照数字的形式排序;
还有就是是否支持多个排序条件,比如说每行中有两个部分,在第一个部分相同时对第二个部分按照指定规则排序;
当然以上说的排序功能是目前已知排序功能的最顶级的,vim能实现就是天大的惊喜,没有实现也是可以理解,但是通过python插件应该是可以实现的吧?
Reply