List variables with prefix where the prefix is stored in another variable

Bash doesn't parse nested variable expansions. You can do what you want with eval: build the shell snippet ${!apple_@}, then use it in a command that you execute with eval.

prefix=apple_
eval 'vars=(${!'"$prefix"'@})'

Make sure that prefix contains only valid identifier characters, otherwise the snippet could result in anything.

eval is usually necessary to work with variables whose name is calculated dynamically, but in this specific case there's a completely different way to do the same thing: use the completion system. Bash's completion system works even from a script. The compgen builtin lists one completion per line, which is ambiguous when completions can contain newlines, but this isn't the case here — they don't even contain wildcard characters, so the output can be split with a simple unquoted expansion. This will safely output nothing if the prefix contains characters that aren't valid in identifiers.

vars=($(compgen -v "$prefix"))

You could use env | grep '^prefix'.

For example:

$ env | grep '^LESS'
LESSBINFMT=*u.
LESS=-MMqx4ij3
LESSOPEN=| /usr/bin/lesspipe %s
LESSCLOSE=/usr/bin/lesspipe %s %s

If you only want the values and not the variable names, use awk:

$ env | awk -F= '/^LESS/ {print $2}'
*u.
-MMqx4ij3
| /usr/bin/lesspipe %s
/usr/bin/lesspipe %s %s

(or print $1 for just the variable names)


Update 2019-05-17

I was brought back to this answer by an upvote, and realised there's an obvious improvement:

typeset -p works better than env, it outputs all variables whether they're exported or not. For example:

typeset -p | awk '$3 ~ /^apple_/ { print $3 }'

To use a variable rather than a fixed string:

prefix=apple_
typeset -p | awk '$3 ~ "^"pfx { print $3 }' pfx="$prefix" 

or just export $prefix so it's available in awk's ENVIRON array:

export prefix=apple_
typeset -p | awk '$3 ~ "^"ENVIRON["prefix"] { print $3 }'

Note: with a little work, this can be made to work with other shells such as ksh or zsh, but it is important to note that the output format for typeset -p is different in other shells, so the awk script will have to be modified to suit them.