如何在vim中打乱列表?

Posted

技术标签:

【中文标题】如何在vim中打乱列表?【英文标题】:How to shuffle a list in vim? 【发布时间】:2013-07-12 15:45:07 【问题描述】:

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

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

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

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

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

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

找不到最好的方法。

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

【问题讨论】:

有用:Native Vim Random number script。我看到你已经知道那里的算法了。 对于 Vim 脚本中更重量级的随机数生成器,还有Rndm。 我昨天检查了本机 Vim 随机脚本,但发现这些值不是随机创建的(请参阅我在该页面上的评论)。我还检查了 Chip Campbell 的 Rndm 脚本,但发现排序也不是随机的(除此之外,还有很多代码) 【参考方案1】:

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

:10,20!shuf<CR>

【讨论】:

我选择的武器::'&lt;,'&gt;!sort -R,或者使用rl from randomize-lines @sehe,谢谢您的回复。 sort! -R 在我看来不是一个很好的随机排序(这是我之前的随机排序命令)。 rl 在我的电脑上不起作用。什么都没有发生。 @Remonn 对于为什么:!sort -R 不能进行良好的随机排序,您有什么实质性的主张吗?由于我只是比较了 sort.cshuf.c 实现,因此我不得不稍微让 sort.c 更加通用(例如尝试sort -uR,或使用特定的键)。 perl -M"List::Util qw(shuffle)" -e "print shuffle &lt;&gt;" input.txt &gt; output.txt【参考方案2】:

截至 2019 年的更新:

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

:'&lt;,'&gt;!sort -R

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

Sort 在 osx 中没有 -R 标志,所以:

brew install coreutils

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

:'&lt;,'&gt;!gsort -R

【讨论】:

从 2019 年开始,sort 在 macOS 中带有 -R 标志,因此不再需要使用 gsort。 我在linux上使用:%!sort -R【参考方案3】:

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

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

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

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

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

然后

:sor n

最后删除添加的前缀:

%s/^\S* //

你当然可以用&lt;bar&gt; 链接上面的命令。

%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

希望对你有帮助

【讨论】:

非常感谢肯特。我注意到它每 8、9、10 行对行进行分组。也可以在这里查看我的评论:***.com/q/12737977 我最终决定使用shuf 命令(我已经安装了 cygwin),即使我更喜欢只使用 vimscript。这也搜索一个随机值,非常好exe 'normal! '.(system('sh -c "echo -n $RANDOM"') % 1000),但是对每一行执行此操作都会连续闪烁我的 VIM 窗口(使用 bash shell) 我发布了答案,假设您没有可用的外部 shuf、sort 或 shell $RANDOM 变量。如果如你所说,你有这些东西,shuf 将是最直接的方法,我也会这样做。我的命令是一种解决方法。 而且,我看不到it groups lines every 8,9,10 lines,您可以在我的答案中查看两次运行的结果。我检查了另一个问题和答案,我们的想法相同,但取的数字不同。 肯特,也许我和你一样使用另一个时间标准?在我的电脑上测试时,我清楚地看到了一组线条。【参考方案4】:

你可以编写一个 python 脚本来帮助 vim 中的随机。 我创建了一个名为pyrandom.py 的python 文件。然后添加执行模式chmod +x pyrandom.py,最后就是将pyrandom.py的目录添加到PATH,可以暂时运行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

【讨论】:

以上是关于如何在vim中打乱列表?的主要内容,如果未能解决你的问题,请参考以下文章

Python 如何随机打乱列表(List)排序

Python面试必考重点之列表,元组和字典第四关——编写一个函数(不要使用python模块的函数),打乱列表元素的顺序/如何对列表元素进行随机排列

打乱 Python 列表

如何在 vim 命令中使用正则表达式格式化电话号码列表?

如何在 eclipse vrapper 中使用 vim 样式的 ctrl p 列表?

当我在vim中填写git commit消息时,如何在文件列表中显示不同的颜色