10

I am looking for a way to echo names and values of all env variables that start with nlu_setting, so the output might look like:

nlu_setting_json=true
nlu_setting_global=0
nlu_setting_bar=foo

does anyone know how to do this?

1
  • 1
    Environment variables? Or shell variables? The difference is important, as it rules in/out several answers.
    – JdeBP
    Aug 4, 2018 at 8:45

4 Answers 4

12
for var in "${!nlu_setting_@}"; do
    printf '%s=%s\n' "$var" "${!var}"
done

The expansion ${!nlu_setting_@} is a bash-specific expansion that returns a list of variable names matching a particular prefix. Here we use it to ask for all names that start with the string nlu_setting_. We loop over these names and output the name along with the value of that variable.

We get the value of the variable using variable indirection (${!var}).

3
  • do you think this is better than the compgen solution? Aug 4, 2018 at 7:47
  • @AlexanderMills I would say that it will be more efficient as it's not calling grep. Your solution would also pick up variable names that contain nlu_setting_ anywhere, not just at the start of the variable name (due to the non-anchored regular expression that you are using).
    – Kusalananda
    Aug 4, 2018 at 7:53
  • ah yes good point Aug 4, 2018 at 17:11
4

After looking at the answers to this question, I came up with this:

   compgen -A variable nlu_setting_ | while read v; do
            echo "$v = ${!v}";
   done

it seems to work. Never heard of the compgen command, but if it's universal bash built-in, it should be all good..

4

Both older answers are good, yet I came with my own:

env | grep ^nlu_setting_ | while read kv; do echo "$kv"; done

Doesn't distinguish for key and value, and uses grep, but that's exactly what I wanted - only env variables, only starting with proper prefix. Maybe someone will find this variant useful.

3
  • Why do you include ⁠ | while read kv; do echo "$kv"; done?  That adds nothing to env | grep '^nlu_setting_' except a waste of resources. May 25, 2022 at 17:18
  • This doesn't seem to add much to the answers from kusalananda (for bash) or from stephane (for zsh) other than the addition of grep. Both previous answers give exactly what you wanted so why change a good thing?
    – doneal24
    May 25, 2022 at 18:08
  • 1
    @doneal24: To be fair, this does appear to be the only correct answer. All the others list shell variables, which are a superset of environment variables. May 25, 2022 at 23:24
0

For those wanting to do the same in zsh, the -m option of typeset can be used to list the variables that match a pattern:

$ typeset -m 'nlu_setting_*'
nlu_setting_1=scalar
nlu_setting_2=( some array )
nlu_setting_3=( [associative]=array [now]=some )

To include the information of type:

$ typeset -pm 'nlu_setting_*'
typeset nlu_setting_1=scalar
typeset -a nlu_setting_2=( some array )
typeset -A nlu_setting_3=( [associative]=array [now]=some )

To list parameters whose name matches a pattern:

$ print -rC1 ${(kM)parameters:#nlu_setting_*}
nlu_setting_1
nlu_setting_2
nlu_setting_3

The values of the $parameters special associative arrays is the type of the variable. So to list only scalar ones for instance:

$ print -rC1 ${(kM)parameters[(R)scalar]:#nlu_setting_*}
nlu_setting_1

(using Reverse subscripting).

To print the corresponding name and value, beside using typeset -m, you can do:

$ for v (${(kM)parameters[(R)scalar]:#nlu_setting_*}) printf '%s=%q\n' $v ${(P)v}
nlu_setting_1=scalar

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .