2010-10-29 10 views
5

Je souhaite mélanger les lignes (les lignes) d'un fichier au hasard, puis imprimer cinq fichiers différents.Génération de nombres aléatoires avec awk dans le shell BASH

Mais je continue d'avoir exactement le même ordre de lignes apparues dans les fichiers 1 à 5. Le processus de génération aléatoire ne fonctionne pas correctement. Je serais reconnaissant pour tous les conseils.

#!/bin/bash 
for i in seq 1 5 
do 
    awk 'BEGIN{srand();} {print rand()"\t"$0}' shuffling.txt | sort -k2 -k1 -n | cut -f2- > file$i.txt 
done 

Entrée shuffling.txt

111 1032192 
111 2323476 
111 1698881 
111 2451712 
111 2013780 
111 888105 
112 2331004 
112 1886376 
112 1189765 
112 1877267 
112 1772972 
112 574631 

Répondre

15

Si vous ne fournissez pas une graine à srand, il utilisera la date et l'heure. Cela signifie que si vos processus s'exécutent assez rapidement, ils utiliseront tous la même graine et généreront la même séquence.

Vous pouvez contourner cela en utilisant une graine différente, fournie par la coque.

awk -v seed=$RANDOM 'BEGIN{srand(seed);}{print rand()" "$0}' ... 

Le numéro fourni par $RANDOM changements dans chaque itération afin que chaque exécution du programme awk obtient une graine différente.

Vous pouvez le voir en action dans la transcription suivante:

pax> for i in $(seq 1 5) ; do 
...> awk 'BEGIN{srand();print rand()}' 
...> done 
0.0435039 
0.0435039 
0.0435039 
0.0435039 
0.0435039 

pax> for i in $(seq 1 5) ; do 
...> awk -v seed=$RANDOM 'BEGIN{srand(seed);print rand()}' 
...> done 
0.283898 
0.0895895 
0.841535 
0.249817 
0.398753 
2
#!/bin/bash 
for i in {1..5} 
do 
    shuf -o "file$i.txt" shuffling.txt 
done 
1

pseudo-aléatoire de Awk est pas très aléatoire, vous devez garder le semis, vous devriez être en mesure d'utiliser microsecondes pour la plupart des situations , sinon vous pouvez regarder en Bash ${RANDOM} ou frapper /dev/urandom directe:

awk 'BEGIN{"date +%N"|getline rseed;srand(rseed);close("date +%N");print rand()}'

for((i=1;i<=5;i++));do awk 'BEGIN{"date +%N"|getline rseed;srand(rseed);close("date +%N");print rand()}';done 
Questions connexes