The following command picks a random line (excluding the header) from the output of the gcloud command, then stores the first two "words" into machine and zone variables:
read -r machine zone unused <<< $(
gcloud compute instance-groups list-instances workers | \
perl -e '@_ = <>; shift @_; print $_[rand @_]'
)
After this command you are ready to use machine and zone variables, e.g.:
gcloud compute --project "my-project" ssh --zone "$zone" "$machine"
Explanations
The perl command reads all lines from the standard input into @_ array using the diamond operator <>. Then shift function removes the first item from @_. rand@_ returns a random decimal number between zero and the number of items in @_. The decimal number is implicitly converted to integer in the index context. Therefore, the result of $_[rand @_] is a random item of @_, i.e. a random line from the output of the gcloud command.
The output of gcloud and perl commands is captured using command substitution and passed to the read command via here string.
I have quoted words in the first paragraph, because the shell interprets character sequences as words depending on the IFS (Input Field Separators) variable. So the IFS-separated words from the here string are assigned to machine (the first word), zone (the second word), and unused (the rest of the line) variables.
-r option disables the special meaning of backslash. In other words, read will not try to interpret escape sequences in the input, when this option is given.
The Case of Big Number of Lines
Note, the solution implies that the output of gcloud command is relatively small, i.e. small enough to slurp the entire file into an array. This operation is fast, but requires more memory as opposed to reading line by line using a while <> loop. Here is another solution for the off-chance if the output is very large, or memory is very limited:
read -r machine zone unused <<< $(
gcloud compute instance-groups list-instances workers | \
perl -e '<>; $. = 0; rand($.) < 1 && ($line = $_) while <>; print $line'
)
where <> reads the header; $. is the built-in variable keeping the current line number; and the rest is taken from this cookbook.