How to shuffle a list in vim?
Solution 1
You could go "UNIX style" and use the shuf
command from the coreutils
package:
:10,20!shuf<CR>
Solution 2
UPDATE as of 2019:
osx now includes a -R
flag in sort, so you should be able to just use
:'<,'>!sort -R
=== Previous answer: ===
Sort does not have a -R flag in osx, so:
brew install coreutils
select lines in vim, and run:
:'<,'>!gsort -R
Solution 3
if you need a uniformed random number generator, I don't know if vim could provide you one native (or you could turn to some plugins). however, if you just want to break some order of a number of lines, you could try this function:
function! Random()
return reltimestr(reltime())[-2:]
endfunction
the function above return the last two digits of current timestamp in ms.
to shuf lines, you could (for example the whole buffer)
%s/^/\=Random() . " "
then
:sor n
finally remove added prefix:
%s/^\S* //
You could of course chain the commands above with <bar>
.
%s/^/\=Random() . " "/|sor n|%s/^\S* //
or without creating the function, write the random number part in your :s
:
%s/^/\=reltimestr(reltime())[-2:] . " "/|sor n|%s/^\S* //
If I test 30 lines with value 1-30 (generated by seq 30
),
first time result was:
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
2nd time result:
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
hope it helps
Solution 4
you can write a python script to help random in vim.
I create a python file named pyrandom.py
. then add the execution mode, chmod +x pyrandom.py
, last thing you need is adding the directory of the pyrandom.py
to PATH
, you can run export PATH=$PATH:/directory/to/pyrandom.py/
temporarily to add to PATH
.
now, you select lines in vim, and run: :'<,'>!pyrandom.py
the content in 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
Reman
Updated on June 24, 2022Comments
-
Reman almost 2 years
What is the best way to shuffle a list in Vim?
I'm trying to randomly sort lines in vim (using vimscript). I created for this a list with all line numbers (in my selection).
p.e. if I select from line 10 to 20 my list will be:
mylist = ['10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20']
I would like to sort the lines randomly and with a for loop put them back in the same selection in the new sequence. In order to realize this I would like to shuffle the list many times but don't know how to shuffle the list.
Another solution would be to pick an index from my last randomly.
Can't find out what is the best way.
I know I can sort lines using python, ruby or with other languages but I don't want to install them. I would like to realize above using vimscript.
-
sehe almost 11 yearsMy weapon of choice:
:'<,'>!sort -R
, or userl
fromrandomize-lines
-
Reman almost 11 yearsThank you very much Kent. I noted that it groups lines every 8,9,10 lines. See also my comment here: stackoverflow.com/q/12737977 I finally decided to use the
shuf
command (I already have cygwin installed) even if I prefer to use only vimscript. This one search a random value as well and is very niceexe 'normal! '.(system('sh -c "echo -n $RANDOM"') % 1000)
but doing this for every line it flickers my VIM window continuously (using the bash shell) -
Reman almost 11 years@sehe, Thank you for your reply.
sort! -R
does in my opinion not a very good random sort (This was my previous sorting randomly command).rl
doesn't work on my pc. Nothing happens. -
Kent almost 11 yearsI posted the answer, assume you don't have external shuf, sort or the shell
$RANDOM
variable available. if as you said, you have those stuff,shuf
would be the most straightforward way, I would go this way as well. My command is kind of workaround. -
Kent almost 11 yearsand, I cannot see
it groups lines every 8,9,10 lines
you can checkout the result of two runs in my answer. I checked the other question and answer, we got same idea, but taking the different numbers. -
sehe almost 11 years
-
Reman almost 11 yearsKent, maybe I'm using another time standard as you do? I clearly see a grouping of lines when I test it on my pc.
-
Alexander Farber about 9 years
perl -M"List::Util qw(shuffle)" -e "print shuffle <>" input.txt > output.txt
-
take over 5 yearsAs of 2019, sort has a -R flag in macOS, so it is no longer necessary to use gsort.
-
Edgard Leal about 3 yearsI used
:%!sort -R
on linux