最后更新于 .

前段时间有博友在群里问了一个关于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,就这样~

Pingbacks

Pingbacks已打开。

Trackbacks

引用地址

评论

  1. 依云

    依云 on #

    Vim 的正则是可以直接指定列位置的,再加上 r 标志,排序多方便~

    可惜不支持浮点数。

    此例用 sort 命令也很简单。

    Reply

  2. yboren

    yboren on #

    如果是linux,也可以调用外部sort命令,:%!sort -t'|' -k3 -r

    Reply

  3. wowo

    wowo on #

    求vim的qq群中多少,我要加群,谢谢。求交流学习。

    Reply

    1. Dante

      Dante on #

      呃,这个真没有,主要是有群的效果并不是太好。。很多知识沉淀不下来

      Reply

  4. 赢球之声-live.779a.com|58i9cz

    赢球之声-live.779a.com|58i9cz on #

    文章太好了,仔细看完了,觉得很精彩,支持下,!!!壬辰年(龙)三月初三 2012-3-24

    Reply

  5. 即时比分-live.779a.cc|z9v3yk

    即时比分-live.779a.cc|z9v3yk on #

    文章太好了,仔细看完了,觉得很精彩,支持下,!!!壬辰年(龙)三月初十 2012-3-31

    Reply

  6. Dino

    Dino on #

    有点不明白,说的是正则匹配的部分就会被排序忽略,例子中的
    :sort /[^,]*,/
    这个 * 是贪心匹配,不仅仅匹配第二列
    可以用一下的文本实验
    sit,Ait,bit
    mat,cat,aggressiv
    用 /[^,]*,/ 可以看出vim匹配了第一和第二列,所以按照说明应该是根据第三列排序,可是事实上还是根据第二列排序的,
    这是为嘛呢 ?

    Reply

    1. Dante

      Dante on #

      不包括,的任意个,并且以,结束

      匹配没错的。

      Reply

  7. bells

    bells on #

    “:sort /|[^|]\+|[^|]\+\s*/”
    其中 "\s" 是指啥呀?
    还有就是感觉最后一个"|"没有匹配上?

    Reply

    1. waveacme

      waveacme on #

      我也觉得,如果要把第3列数据之前的字符做正则匹配的话,似乎应该是这样:

      :sort /|[^|]\+|[^|]\+|\s\+/

      但是像博主那样弄也能得到正确结果,感觉好神奇。

      另外,感谢分享,又学到一招。

      Reply

      1. skywalker

        skywalker on #

        在vi里help 了一下pattern,第4部分overview of 我觉得

        Reply

      2. skywalker

        skywalker on #

        在vi里help 了一下pattern,第4部分overview of pattern items,\s代表空白字符,所以\s*应该是任意多个空白字符,我觉得最后一个|其实匹配与否无所谓,就算不跳过这个|,从第三列排序的时候每一个元素开头都是|字符,所以其实还是从|后面的第一个字符开始sort

        Reply

        1. bells

          bells on #

          有道理,谢谢了。

          Reply

  8. -

    - on #

    博主这里的排序其实还是排除掉无关的部分,对剩下的内容做字符串排序,我非常在意的就是vim能否实现,对指定的部分(利用正则表达式)做指定规则的排序,比如说对第4-8列之间的内容按照数字的形式排序;
    还有就是是否支持多个排序条件,比如说每行中有两个部分,在第一个部分相同时对第二个部分按照指定规则排序;
    当然以上说的排序功能是目前已知排序功能的最顶级的,vim能实现就是天大的惊喜,没有实现也是可以理解,但是通过python插件应该是可以实现的吧?

    Reply

发表评论