0

I have the following code:

n=1

a_letters=("a" "b" "c" "d" "e")

while [ $n -le 3 ]; do
    uniqueLetters=($(printf '%s\n' "${a_letters[@]}"))
    rand=$[ ( $RANDOM % 5)] 
    echo "${uniqueLetters[$rand]}"
    n=$(( $n+1 ))
done

How can I avoid array items that was already printed?

  • 1
    Possible duplicate of [Simple method to shuffle the elements of an array in BASH shell?](https://stackoverflow.com/questions/5533569/simple-method-to-shuffle-the-elements-of-an-array-in-bash-shell) – melpomene Aug 19 '17 at 16:36
  • The `printf` is unnecessary; `uniqueLetters=( "${a_letters[@]}" )` would accomplish the same thing. – chepner Aug 19 '17 at 18:08
  • related: https://stackoverflow.com/q/3846123/4957508 – Jeff Schaller Aug 19 '17 at 18:43

1 Answers1

0

You will have to do some bookkeeping:

2 possibilities:

  1. Remove a used char from the a_letters array
  2. Keep track of printed characters and run the random until you hit an unused one.

I would go for option 1:

n=1

a_letters=("a" "b" "c" "d" "e")

while [ $n -le 3 ]; do
    uniqueLetters=($(printf '%s\n' "${a_letters[@]}"))
    rand=$[ ( $RANDOM % ${#a_letters[@]})] 
    echo "${uniqueLetters[$rand]}"
    a_letters=( "${a_letters[@]/${uniqueLetters[$rand]}}" )
    n=$(( $n+1 ))
done

(untested).

What it does is remove the selected character from your array a_letters and use the array size in the random so that it automatically corrects for the reduced array size.

Norbert
  • 6,026
  • 3
  • 17
  • 40
  • I thought about bookkeeping :-) What if I do want to keep the array elements in tact for future usage? Further more, the result should always be 3 letters. It needs to run once a day. – silverscales Aug 19 '17 at 16:51
  • You could setup a copy array of `a_letters` every loop so that `a_letters` is unchanged (really the most straight forward option). – Norbert Aug 19 '17 at 17:04