Il mio script produce lo stesso output quando si utilizza $ RANDOM


8

Sto cercando di stampare una nlettera casuale , in cui inserisco ndalla stessa riga di comando, ma per qualche ragione il mio script mi ​​dà la stessa risposta ogni volta che uso lo stesso valore per n.

#!/bin/bash                                                                                                                                       
num=$1
egrep "^.{$num}$" /usr/share/dict/words | head -n $RANDOM| tail -n 1

Sto chiamando la mia sceneggiatura come:

$ bash var3.sh 5
étude             # always the same output when using 5 

$ bash var3.sh 3
zoo               # always the same output when using 3

dov'è var3.shil nome della mia sceneggiatura e 5 è la lunghezza della parola che voglio stampare in modo casuale.

Come ottengo per stampare una parola veramente casuale?


3
$RANDOMè molto probabile che sia maggiore del numero di parole n- letter per la maggior parte dei valori di n (il 95,7% delle volte per n = 3 per me).
Michael Homer,

Stai cercando di stampare una parola a caso completamente, anche se non è una parola o stamparla a caso dal dict?
iZodiac

Se l'attività è correlata alla sicurezza (ad esempio per creare una password), è necessario utilizzare uno strumento creato per tale attività. Altrimenti, è possibile utilizzare shufo sort -Rcome suggerito nelle risposte. Puoi anche usare $RANDOM, ma in modo più avanzato. Tutti questi strumenti producono risultati che possono essere previsti (non sono realmente casuali), ma sono veloci e abbastanza buoni per molti scopi.
sudodus,

1
Forse usano questo metodo (riferimento XKCD obbligatorio)
molnarm,

Risposte:


20

Non Ma $ RANDOM restituisce grandi numeri (tra 0 e 32767) che, specialmente per parole di lunghezza limitata, mostrano lo stesso risultato, poiché la headporzione probabilmente restituisce tutti i risultati del grep (per 3, ci sono solo 819 partite nel mio /usr/share/dict/words).

La soluzione migliore potrebbe essere quella di mescolare i risultati:

egrep "^.{$num}$" /usr/share/dict/words | sort -R | tail -n 1

dove -Rsignifica --random-sort( sortun'estensione GNU ).


16
Perché tail? Questo aveva senso nella sceneggiatura di OP, ma dato che stai mescolando potresti anche usare head, e quindi sortdovresti essere in grado di rilevare il tubo rotto e non preoccuparti di mescolare il resto delle linee.
Peter Taylor,

@PeterTaylor probabilmente un buon consiglio. Usare la coda è solo una mia abitudine ... Alla fine, probabilmente preferirei ancora di più la shuf -n1, che è una pipa in meno ...
Jakub Lucký

19

Un metodo semplice per stampare un arbitrario num -Lettera usi di parole shuf:

egrep "^.{$num}$" /usr/share/dict | shuf -n1

Il shufcomando emette una permutazione casuale dell'input e il -n1flag indica che emette solo il primo elemento da questo risultato.


3
o grep -Ex ".{$num}". Or awk 'length == n' n="$num"'.
Stéphane Chazelas,

5

Come altri hanno sottolineato, il problema principale con il tuo codice è che il $RANDOMpiù delle volte sarà un valore molto più grande di allora il numero di parole di una certa lunghezza.

Utilizzando awksolo:

$ awk -v len="$num" 'length == len { word[i++]=$0 }
                     END { print word[int(i*rand())] }' /usr/share/dict/words
Bosniac

Il programma legge in tutte le righe dal file specificato che sono di una certa lunghezza. Questi sono memorizzati nell'array words.

Alla fine, un elemento casuale di questo array viene selezionato e stampato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.