我有一个如下文件:
Pallets
24 1 345 232 345 1 432 45 0 3
some text
more text
COPIES
542 11,456 1,576 1,212 13,229 46,035 9,061 10,642 13,044
CHARGES
225.45 4,464.90 613.91 511.73 5,140.22 17,532.10 3,473.52 4,059.68 5,064.39
是否可以对作为数字列表的每一行进行排序?
就像(我想象的):
如果匹配pattern / ^ \ d + /然后对该行进行排序。
这可能吗?
编辑。这是输出。
Pallets
0 1 1 232 24 3 345 345 432 45
some text
more text
COPIES
542 1,212 1,576 9,061 10,642 11,456 13,044 13,229 46,035
CHARGES
225.45 511.73 613.91 3,473.52 4,059.68 4,464.90 5,064.39 5,140.22 17,532.10
编辑。这是我到目前为止所做的(忽略逗号和小数部分)
%s/\n\(\d.*\)\n/\rSTART\r\1\rEND\r/
g/^\d/ s/ /\r/g
#Throwing away decimal for now..
g/^\d/ s/,\|\.\d\+//
g/START/+,/END/- sort
g/START/+,/END/- s/\n/ /
%s/ END$//
g/^START/d
答案 0 :(得分:4)
您可以先将记录拆分为单独的行,对它们进行排序,然后重新加入:
:s/ /\r/g
:'[,']sort
:'[,']join
如果您不使用空格作为分隔符,则必须使用:s
重新加入:
:'[,']s/\n/,/
'[,']
可以方便地选择修改后的范围(从行的初始分割开始),因此您无需使用行号或人工引入BEGIN..END保护。
答案 1 :(得分:1)
我想我会从全局:g
命令中使用setline(),split()和sort()。
这比初看起来更难,因为我们需要将数字转换为浮点数,而且我们还需要删除逗号:
g#^\d\+#call setline('.', join(sort(map(split(getline('.')), "str2float(substitute(v:val, ',', '', 'g'))"), 'n')))
编辑:这依赖于sort()
函数的'n'标志,该标志在7.4.341中添加,以允许对数字进行排序,而不是始终将它们视为字符串。在旧版本的Vim中,您仍然可以使用此解决方案,而不是“n”传递可以比较项目的函数名称。有关如何创建此类函数的详细信息,请参阅:help sort()
和示例。注意,使用这种方式的函数,也可以让你保持逗号格式等,而上面给出的直接解决方案删除了逗号,即使原始行只有一个整数,也总是加一个小数。
替代方法:如果您不喜欢使用set / getline函数,您也可以在一个替换命令中执行整个操作,该命令以相同的方式执行匹配整行的替换一个数字:
:%s/^\d\+.*/\=join(sort(map(split(submatch(0)), "str2float(substitute(v:val, ',', '', 'g'))"), 'n'))/e
这以相同的方式工作,但使用submatch(0)
而不是getline('.')
,并依赖于\=
项的表达式替换。有关详细信息,请参阅:help submatch()
和:help sub-replace-expression
。我怀疑存在明显的速度差异,因此您使用的方法更多是个人偏好。