2017-01-31 9 views
1

숫자가 1 ... N 인 정수 배열을 만들고 싶습니다. 각 숫자는이 배열에 한 번 나타납니다. N은 =이 어레이를 생성하기 위해 제씨앗을 사용하여 bash에서 번호를 뒤섞기

, 난 같이 셔플 방식을 사용할 때 인스턴스 어레이 = {1, 3, 5, 2, 4}

 array=($(shuf -i 1-$N -n $N)) 

잘 작동. 그러나 동일한 시드로 코드를 실행할 때마다 동일한 배열을 얻을 수 있도록이 코드에 시드를 추가하려고합니다. 셔플 방법을 사용하여이를 수행 할 수 있습니까?

+0

"shuf"의 특정 구현은 무엇입니까? –

+0

실제로 배열로 읽어들이는 것은 실제로 좋은 방법은 아닙니다. bash 4.0 이상이거나'IFS = $ '\ n'읽기 -r -d ''-a 배열 <<(shuf -i "1- $ N"-n "$)이면'readarray' 또는'mapfile'을 고려하십시오. N "&& printf '\ 0')'bash 3.x 지원 - 문자열 분할에 의존하지 않고 (따라서 IFS의 현재 값에 의존하고 실수로 glob 확장을 실행 함). 아무래도 –

+1

. GNU'shuf' ('shuf'는 bash의 일부가 아니기 때문에 별도로 선적 된 도구이기 때문에 말할 수 없습니다)라면'--random-source'가 할 것입니다. –

답변

1

shuf의 GNU 구현은 --random-source 인수를가집니다. 이 인수를 알려진 내용이있는 파일의 이름으로 전달하면 신뢰할 수있는 출력 집합이됩니다. 문자열에 의존하지 않는 방식으로 떠들썩한 배열로 결과를로드 할 수

get_seeded_random() 
{ 
    seed="$1" 
    openssl enc -aes-256-ctr -pass pass:"$seed" -nosalt \ 
    </dev/zero 2>/dev/null 
} 

shuf -i1-100 --random-source=<(get_seeded_random 42) 

:

는 다음의 샘플 구현이 들어있는 GNU의로 coreutils 설명서에 Random sources 문서를 참조하십시오 -splitting (따라서 IFS의 현재 값), 구현 대신 같이 보일 수 있습니다 : 혼자 배쉬에서

# with bash 4.0 or newer 
readarray -t array < <(shuf -i1-100 --random-source=<(get_seeded_random 42)) 

# or, supporting bash 3.x as well 
IFS=$'\n' read -r -d '' -a array \ 
    < <(shuf -i1-100 --random-source=<(get_seeded_random 42) && printf '\0') 
+0

고마워, 내가 배쉬 4.3을 사용하고 완벽하게 잘 작동합니다. 귀하의 도움은 대단히 감사하겠습니다. – begumgenc

1

(외부에 사용하지 않고 shuf 또는 openssl 같은 OLS, 당신은 당신과 같이 의사 난수 입력을 시드 할 수 $RANDOM 사용할 수 있습니다

RANDOM=$$ 

또는

RANDOM=$(date '+%s') 

을 그리고 당신의 범위를 선택할 수 있습니다 숫자는 {1..N}과 같은 표현식을 사용합니다.

declare -a a=() 
for n in {1..5}; do 
    a[$RANDOM]=$n 
done 
echo "${a[@]}" 

상기 코딩 된 용액으로는, 비트 시프트를 이용하여, 예를 들어, 임의의 범위를 확장하여 일부 추가 코드를 경감 또는 감소시킬 수있는 반복되는 랜덤 값의 경우에 실패의 비제 위험을 가지고 대신에 15 비트 부호없는 정수의 30 비트 부호없는 정수로 만들려면 :

... 
    a[$(((RANDOM<<15)+RANDOM))]=$n 
... 
떠들썩한 파티에서, 비 결합 배열의 요소가 자연스럽게 값 수치 적 순서 때문에이 솔루션의 출력은 "랜덤 화"된다

그들의 색인의.

"순차적"은 유효한 임의 순서입니다. :-)

$ a=(); for n in {1..5}; do a[$RANDOM]=$n; done; declare -p a 
declare -a a=([7460]="5" [12697]="3" [16841]="2" [21485]="1" [32493]="4") 
$ a=(); for n in {1..5}; do a[$RANDOM]=$n; done; declare -p a 
declare -a a=([1444]="1" [12162]="2" [17774]="3" [29827]="4" [31840]="5")