2010-10-29 35 views
5

Tôi muốn xáo trộn các dòng (các hàng) của một tệp một cách ngẫu nhiên rồi in ra năm tệp khác nhau.Tạo số ngẫu nhiên với awk trong BASH shell

Nhưng tôi vẫn giữ đúng thứ tự các dòng xuất hiện trong tệp 1 đến tệp5. Quá trình tạo ngẫu nhiên không hoạt động đúng cách. Tôi sẽ biết ơn vì bất kỳ lời khuyên nào.

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

Input 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 

Trả lời

15

Nếu bạn không cung cấp một hạt giống để srand, nó sẽ sử dụng ngày và thời gian hiện tại. Điều đó có nghĩa, nếu các quy trình của bạn chạy đủ nhanh, tất cả chúng sẽ sử dụng cùng một hạt giống và tạo ra cùng một chuỗi.

Bạn có thể giải quyết vấn đề này bằng cách sử dụng một hạt giống khác, do trình bao cung cấp.

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

Các số được cung cấp bởi $RANDOM thay đổi trong mỗi lần lặp nên mỗi lần chạy của chương trình awk được một hạt giống khác nhau.

Bạn có thể thấy điều này trong hành động trong bảng sau:

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

AWK của pseudo-ngẫu nhiên không phải là rất ngẫu nhiên, bạn cần phải giữ hạt giống, bạn sẽ có thể sử dụng micro cho hầu hết các tình huống , nếu không bạn có thể muốn xem xét Bash ${RANDOM} hoặc đánh /dev/urandom trực tiếp:

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