1

I have a few strings, and I want to set a variable to one of them, randomly. Say the strings are test001, test002, test003 and test004.

If I set it like normal I'd obviously do it like this:

test=test001

But I want it to choose a random one from the for strings I have. I know I could do something like this, which I have done previously, but that was when choosing a random file from a directory:

test="$(printf "%s\n" "${teststrings[RANDOM % ${#teststrings[@]}]}")"

But in this case I am not sure how to set testrings.

1
  • set the teststrings array like this: teststrings=( test001 test002 test003 test004 ), then your code will work. To save running in a subshell, printf -v test "%s\n" "${teststrings[RANDOM % ${#teststrings[@]}]}" Nov 4, 2015 at 15:01

3 Answers 3

1

Store your strings in an array.

Use jot(1) to choose an array index at random.

Print the array element at that random index.

Consider this script foo.sh:

# initialize array a with a few strings
a=("test1" "test2" "test3" "test4" "test5" "test6")

# get the highest index of a (the number of elements minus one)
Na=$((${#a[@]}-1))

# choose:  
#    jot -r 1         1 entry, chosen at random from between
#             0       0 and ...
#               $Na     ... the highest index of a (inclusive)
randomnum=$(jot -r 1 0 $Na)

# index the array based on randomnum:
randomchoice="${a[$randomnum]}"

# display the result:
printf "randomnum is %d\na[randomnum] is '%s'\n" \
    $randomnum "$randomchoice"

Output:

$ . foo.sh
randomnum is 3
a[randomnum] is 'test4'
$ . foo.sh
randomnum is 0
a[randomnum] is 'test1'
$ . foo.sh
randomnum is 4
a[randomnum] is 'test5'
$ . foo.sh
randomnum is 1
a[randomnum] is 'test2'
1
array=(test001 test002 test003 test004) ;
rand_var="${array[RANDOM%${#array[@]}]}";
4
  • That method to count how many elements the array has will break if any element contains whitespace, or if there are glob-patterns that match files. Simply use totalstr=${#array[@]}. Nov 4, 2015 at 15:58
  • You don't need to nest arithmetic expressions: $(( (RANDOM % totalstr) + 0 )) will do, but you don't need to add zero: why do you do that? Nov 4, 2015 at 15:58
  • Thanks , I d no idea about the array count, that's why ... !
    – Yunus
    Nov 4, 2015 at 18:26
  • 1
    @glennjackman, array indices are already evaluated as arithmetic expressions, so it's just rand_var="${array[RANDOM % ${#array[@]}]}" May 31, 2020 at 20:53
0

You can still do something similar:

v=$(printf "test%03d" $(($RANDOM%4+1)))
v=${!v}

where bash ${!variable} does one level of indirection towards the real variable test001 etc.


When the names of the variables can be anything, eg test001 somevar anothervar, setup an array:

declare -a teststrings=(test001 somevar anothervar)
v=${teststrings[$(($RANDOM % ${#teststrings[*]}))]}
w=${!v}
echo $w
2
  • Good answer, but unfortunetaly I might have written my question a bit wrong. The strings can be anything, not just the same thing with increasing numbers. Sorry. Nov 4, 2015 at 14:54
  • can you put all the variable names in an array?
    – meuh
    Nov 4, 2015 at 14:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.