2010-10-29 13 views
5

Deseo mezclar aleatoriamente las líneas (las filas) de un archivo al azar y luego imprimirlas en cinco archivos diferentes.Generación aleatoria de números con awk en el shell BASH

Pero sigo teniendo exactamente el mismo orden de líneas que aparecen en el archivo1 al archivo5. El proceso de generación aleatorio no funciona correctamente. Agradecería cualquier consejo.

#!/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 

entrada 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 

Respuesta

15

Si usted no proporciona una semilla a srand, se utilizará la fecha y la hora actuales. Eso significa que, si sus procesos se ejecutan lo suficientemente rápido, todos usarán la misma semilla y generarán la misma secuencia.

Puede evitar esto utilizando una semilla diferente, proporcionada por el caparazón.

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

El número proporcionado por $RANDOM cambios en cada iteración por lo que cada ejecución del programa awk obtiene una semilla diferente.

Esto se puede ver en acción en el siguiente transcripción:

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

de Awk pseudo-aleatorio no es muy aleatorio, es necesario mantener la siembra, usted debería ser capaz de utilizar microsegundos para la mayoría de las situaciones , de lo contrario puede que desee ver en Bash ${RANDOM} o golpear /dev/urandom directa:

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