Генерация случайных чисел с помощью awk в оболочке BASH - PullRequest
6 голосов
/ 29 октября 2010

Я хочу перемешать строки (строки) файла в случайном порядке, а затем распечатать в пять различных файлов.

Но у меня точно такой же порядок строк, как в файлах от 1 до 5. Процесс генерации случайных чисел не работает должным образом. Буду благодарен за любые советы.

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

Ввод 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

Ответы [ 3 ]

18 голосов
/ 29 октября 2010

Если вы не предоставите начальное значение для srand, оно будет использовать либо текущую дату и время, либо фиксированное начальное начальное число (это может варьироваться в зависимости от реализации). Это означает, что для первых, если ваши процессы работают достаточно быстро, все они будут использовать один и тот же начальный поток и генерировать одну и ту же последовательность.

И, для последнего, не имеет значения, как долго вы будете ждать, вы будете получать одинаковую последовательность при каждом запуске.

Вы можете обойти любой из них, используя другое семя, предоставленное оболочкой.

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

Число, предоставляемое $RANDOM, изменяется в каждой итерации, поэтому каждый запуск программы awk получает различное начальное число.

Вы можете увидеть это в действии в следующей расшифровке:

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 голосов
/ 29 октября 2010
#!/bin/bash
for i in {1..5}
do
    shuf -o "file$i.txt" shuffling.txt
done
1 голос
/ 24 мая 2016

Псевдослучайность в Awk не очень случайна, вам нужно продолжать посев, вы должны иметь возможность использовать микросекунды для большинства ситуаций, в противном случае вы можете захотеть посмотреть на Bash ${RANDOM} или нажать /dev/urandom direct:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...