As the set
builtin of FreeBSD sh
outputs in a format that is suitable for reinput to the shell, you can do:
out() case $1 in (_myvar_*) printf '%s\n' "${1%%=*}"; esac
eval "$(set | sed 's/^/out /')"
That is prefix each line of the output of set
with "out "
and have that evaluated as shell code (where out
is a function that prints the substring of its first argument up to the first =
).
sed
would also insert "out "
in the content of multiline variable, but that would still be included in the argument that our out
function receives and past the first =
, so in the part we're not displaying.
For instance, on a set
output like:
TERM=xterm
USER=stephane
_myvar_foo='line1
line2
line3'
We would be evaluating:
out TERM=xterm
out USER=stephane
out _myvar_foo='line1
out line2
out line3'
But that's still fine as out
is only called 3 times for those 3 variables.
To print both variable name and value:
out() case $1 in (_myvar_*)
eval 'printf "name: \"%s\" value: \"%s\"\n" "${1%%=*}" "${'"${1%%=*}"'}"'
esac
eval "$(set | sed 's/^/out /')"
Note that it only outputs variables, not other types of parameters like $-
, positional parameters...
That approach only works for sh
implementations where set
only outputs scalar variables (won't work for arrays or associative arrays or compound variables, where out var=(x)
becomes a syntax error). Those shells that have other variable types often also have better introspection features.
In zsh
:
typeset -pm '_myvar_*'
or for the names only
echo $parameters[(I)_myvar_*]
In bash
:
v=("${!_myvar_@}"); ((${#v[@]})) && typeset -p -- "${v[@]}"
echo "${!_myvar_@}"
Best Answer
In
zsh
oryash
.would work as you'd expect.
Otherwise, in
bash
, you can still do:POSIXly, you can do the quoting by hand using
awk
:For fun, a hacky solution that works in some shells (
bash
,zsh
,mksh
,ksh93
, notyash
nordash
):