30

在 Vim 中打乱列表的最佳方法是什么?

我正在尝试对 vim 中的行进行随机排序(使用 vimscript)。我为此创建了一个包含所有行号的列表(在我的选择中)。

pe 如果我从第 10 行到第 20 行中选择,我的列表将是:

mylist = ['10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20']

我想对这些行进行随机排序,并使用 for 循环将它们放回新序列中的相同选择中。为了实现这一点,我想多次洗牌,但不知道如何洗牌。

另一种解决方案是从我的最后一个随机选择一个索引。

找不到最好的方法。

我知道我可以使用 python、ruby 或其他语言对行进行排序,但我不想安装它们。我想使用 vimscript 实现上述功能。

4

4 回答 4

42

您可以使用“UNIX 风格”并使用包中的shuf命令coreutils

:10,20!shuf<CR>
于 2013-07-14T20:28:03.297 回答
15

截至 2019 年的更新:

osx 现在-R在排序中包含一个标志,因此您应该可以使用

:'<,'>!sort -R

=== 上一个答案:===

Sort 在 osx 中没有 -R 标志,因此:

brew install coreutils

在 vim 中选择行,然后运行:

:'<,'>!gsort -R

于 2014-08-17T22:45:50.827 回答
4

如果您需要一个统一的随机数生成器,我不知道 vim 是否可以为您提供一个本机(或者您可以求助于一些插件)。但是,如果你只是想打破一些行的顺序,你可以试试这个功能:

function! Random()
    return reltimestr(reltime())[-2:]
endfunction

上面的函数以毫秒为单位返回当前时间戳的最后两位数。

换行,你可以(例如整个缓冲区)

%s/^/\=Random() . " "

然后

:sor n

最后删除添加的前缀:

%s/^\S* //

您当然可以将上面的命令与<bar>.

%s/^/\=Random() . " "/|sor n|%s/^\S* //

或不创建函数,将随机数部分写入您的:s

%s/^/\=reltimestr(reltime())[-2:] . " "/|sor n|%s/^\S* //

如果我测试 30 行值为 1-30(由 生成seq 30),

第一次结果是:

2
26
12
17
8
22
27
3
13
18
23
9
28
4
14
19
1
24
10
29
5
6
15
20
25
30
11
16
7
21

第二次结果:

4
22
25
28
6
9
18
12
15
1
3
5
21
24
27
30
8
11
17
14
2
20
23
26
29
7
10
16
13
19

希望能帮助到你

于 2013-07-14T21:41:11.593 回答
2

你可以编写一个 python 脚本来帮助 vim 中的随机。我创建了一个名为pyrandom.py. 然后添加执行模式,chmod +x pyrandom.py最后你需要添加的目录pyrandom.pyPATH你可以export PATH=$PATH:/directory/to/pyrandom.py/临时运行添加到PATH

现在,您在 vim 中选择行,然后运行: :'<,'>!pyrandom.py

pyrandom.py 中的内容

#!/usr/bin/python
import sys
import random

all_lines = []
for line in sys.stdin:
    all_lines.append(line.rstrip('\n'))

random.shuffle(all_lines)

for line in all_lines:
    print line
于 2016-11-22T12:10:05.033 回答