2013-07-14 18 views
13

Qual è il modo migliore per mescolare un elenco in Vim?Come mescolare un elenco in vim?

Sto cercando di ordinare le righe in modo casuale in vim (utilizzando vimscript). Ho creato per questo una lista con tutti i numeri di riga (nella mia selezione).

p.e. se seleziono dalla linea 10 a 20 la mia lista sarà:

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

Vorrei ordinare le linee in modo casuale e con un ciclo for metterli di nuovo nella stessa selezione nella nuova sequenza. Per realizzare questo mi piacerebbe mescolare la lista molte volte ma non so come mischiare la lista.

Un'altra soluzione sarebbe quella di scegliere un indice dal mio ultimo a caso.

Impossibile scoprire qual è il modo migliore.

So che posso ordinare le linee usando python, ruby ​​o con altri linguaggi ma non voglio installarli. Mi piacerebbe realizzare sopra usando vimScript.

+0

utili: [Native Vim a caso numero script] (http://stackoverflow.com/q/12737977). Vedo che sei già a conoscenza dell'algoritmo lì. – glts

+1

Per un generatore di numeri casuali più pesante in Vim c'è anche [Rndm] (http://www.drchip.org/astronaut/vim/index.html#RNDM). – glts

+0

Ho controllato il Native Vim Random Script ieri ma ho scoperto che i valori non sono stati creati casualmente (vedi il mio commento su quella pagina). Ho controllato anche la sceneggiatura Rndm di Chip Campbell, ma ho scoperto che l'ordinamento non è casuale (e soprattutto, c'è molto codice in esso) – Reman

risposta

18

Si potrebbe andare "stile UNIX" e utilizzare il comando shuf dal pacchetto coreutils:

:10,20!shuf<CR> 
+8

La mia arma preferita: ': '<,'>! Sort -R', o usa 'rl' da' randomize-lines' – sehe

+1

@sehe, grazie per la tua risposta. 'Ordinare! -R' a mio parere non è un ottimo ordinamento casuale (questo era il mio precedente comando di ordinamento casuale). 'rl' non funziona sul mio pc. Non accade nulla. – Reman

+3

@Remonn Hai qualche pretesa sostanziale sul perché ':! Sort -R' non fa un buon ordinamento casuale? Poiché ho appena confrontato ** [sort.c] (http://lingrok.org/xref/coreutils/src/sort.c) ** e ** [shuf.c] (http://lingrok.org/xref /coreutils/src/shuf.c)** implementazioni, e devo dare un leggero vantaggio a sort.c per essere più versatile (es. prova 'sort -uR', o usando una chiave specifica). – sehe

4

se avete bisogno di un generatore di numeri casuali in divisa, non so se vim potrebbe fornire un nativo (oppure potresti girare ad alcuni plugin). tuttavia, se si desidera solo rompere un ordine di un certo numero di righe, si potrebbe provare questa funzione:

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

la funzione di cui sopra restituire le ultime due cifre del timestamp corrente in ms.

alle linee SHUF, si potrebbe (ad esempio l'intero buffer)

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

poi

:sor n 

prefisso infine rimuovi aggiunto:

%s/^\S* // 

Si potrebbe catena naturalmente il comandi sopra con <bar>.

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

o senza creare la funzione, scrivere la parte numero casuale nel :s:

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

Se risulto 30 linee con valore 1-30 (generato da seq 30),

primo Il risultato è stato:

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 

risultato 2 ° tempo:

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 

Speranza che aiuta

+0

Grazie mille Kent. Ho notato che raggruppa linee ogni 8,9,10 linee. Vedi anche il mio commento qui: http://stackoverflow.com/q/12737977 Alla fine ho deciso di usare il comando 'shuf' (ho già installato cygwin) anche se preferisco usare solo vimscript. Questo cerca anche un valore casuale ed è molto bello come 'normale'! '.(system ('sh -c "echo -n $ RANDOM"')% 1000) 'ma facendo questo per ogni riga sfarfalla continuamente la mia finestra VIM (usando la shell bash) – Reman

+1

Ho postato la risposta, presumo che tu non abbia shuf esterno, sort o la variabile '$ RANDOM' disponibile. se come hai detto tu hai queste cose, 'shuf' sarebbe il modo più diretto, anch'io andrei in questo modo. Il mio comando è una specie di soluzione alternativa. – Kent

+0

e, non riesco a vedere 'raggruppa le linee ogni 8,9,10 linee ', è possibile verificare il risultato di due esecuzioni nella mia risposta. Ho controllato l'altra domanda e ho risposto, abbiamo avuto la stessa idea, ma abbiamo preso i numeri diversi. – Kent

6

Ordina non ha una bandiera -R in OSX, quindi:

brew install coreutils

selezionare linee in vim, ed eseguire:

:'<,'>!gsort -R

1

puoi scrivere uno script in python lp random in vim. Creo un file python denominato pyrandom.py. quindi aggiungi la modalità di esecuzione, chmod +x pyrandom.py, l'ultima cosa di cui hai bisogno è aggiungere la directory di pyrandom.py a PATH, è possibile eseguire temporaneamente export PATH=$PATH:/directory/to/pyrandom.py/ da aggiungere a PATH.

ora, si selezionano linee in vim, ed eseguire: :! '<,'> pyrandom.py

il contenuto 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 
Problemi correlati