你如何按长度排序一系列线?

时间:2012-07-17 21:21:56

标签: regex sorting vim

通常我只想按照文件的长度对源文件和文件头顶部的所有#include进行排序。

vim允许我以与:{range} sort u类似的方式按字母顺序排序。

vim中,您如何按行的长度对一系列行进行排序?这样较短的线后面跟着较长的线。

在网上搜索,我发现了这个:

:% s/.*/\=printf("%03d", len(submatch(0)))."|".submatch(0)/ | sor n | %s/..../

但这只能对整个文件进行排序,无论如何对我来说都是黑魔法。我试图弄清楚如何使用范围从第4行到第18行进行同样的排序,如:4,18 s/...中你有任何想法吗?

3 个答案:

答案 0 :(得分:24)

使用Awk过滤视觉选择

在vim中执行此操作的一种方法是在排序之前使用awk的length()函数过滤视觉选择。例如:

:'<,'> ! awk '{ print length(), $0 | "sort -n | cut -d\\  -f2-" }'

答案 1 :(得分:6)

一种方式,既不优雅也不高效,但它有效:

将以下功能添加到vimrc文件中。它在每行的开头插入其字符数,按数字排序并删除数字。

function! SortLines() range
    execute a:firstline . "," . a:lastline . 's/^\(.*\)$/\=strdisplaywidth( submatch(0) ) . " " . submatch(0)/'
    execute a:firstline . "," . a:lastline . 'sort n'
    execute a:firstline . "," . a:lastline . 's/^\d\+\s//'
endfunction

使用一系列数字来调用它,例如

:4,18call SortLines()

或使用V的可视模式,如:

:'<,'>call SortLines()

编辑:Ops,现在我意识到这个解决方案与你的解决方案非常相似。没关系,只有%表示选择特定行的完整缓冲区:4,18:'<,:'>

答案 2 :(得分:4)

我已经写了AdvancedSorters plugin来处理这些复杂的排序要求。

就像在@Birei的回答中一样,这个插件提供了评估每行表达式的扩展命令, 把那个数字放在行前面,做一个数字排序,然后删除 临时号码。专业化按数量处理常见的排序 字符和行的显示宽度,所以你可以使用:

:SortByWidth