Find all environment variables with the same value

Viewed 33

I'm on a linux machine in the command line. I would like to find all of the environment variables with same value.

In my hypothetical/simplified example, let's imagine I run the command printenv and that gives me the output of:

SHELL=/bin/bash
GOOGLE_CLOUD_SHELL=true
GOOGLE_CLOUD_PROJECT=qwiklabs-gcp-04-331618d6c19
JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
CLOUD_SHELL=true
DEVSHELL_PROJECT_ID=qwiklabs-gcp-04-331618d6c19
GCLOUD_PROJECT=qwiklabs-gcp-04-331618d6c19

I am trying to find redundant environment variables. I would like a command that shows me all of the environment variables with the value of qwiklabs-gcp-04-331618d6c19. So I would like a command to show me this output:

GOOGLE_CLOUD_PROJECT=qwiklabs-gcp-04-331618d6c19
DEVSHELL_PROJECT_ID=qwiklabs-gcp-04-331618d6c19
GCLOUD_PROJECT=qwiklabs-gcp-04-331618d6c19

I would also be happy with this output:

GOOGLE_CLOUD_PROJECT
DEVSHELL_PROJECT_ID
GCLOUD_PROJECT

How can I do this?

5 Answers

If all the variables are listed in the output of printenv then:

awk -v value='qwiklabs-gcp-04-331618d6c19' '
    BEGIN {
        for (e in ENVIRON)
            if (ENVIRON[e]==value)
                print e
    }
'

This answer addresses this part of the question:

I would like to find all of the environment variables with same value

As I've been diving into lately:

jq -rn '
    $ENV 
    | to_entries 
    | group_by(.value)[]
    | select(length > 1)[]
    | "\(.key)=\(.value | @sh)"
'

Will output, amongst any other sets of env vars that share values:

GOOGLE_CLOUD_PROJECT='qwiklabs-gcp-04-331618d6c19'
DEVSHELL_PROJECT_ID='qwiklabs-gcp-04-331618d6c19'
GCLOUD_PROJECT='qwiklabs-gcp-04-331618d6c19'
GOOGLE_CLOUD_SHELL='true'
CLOUD_SHELL='true'

For that specific value:

jq -rn --arg value qwiklabs-gcp-04-331618d6c19 '
    $ENV
    | to_entries[]
    | select(.value == $value)
    | "\(.key)=\(.value | @sh)"
'

I would like a command that shows me all of the environment variables with the value of qwiklabs-gcp-04-331618d6c19

Most probably I would just do:

env -0 | grep -zx '[^=]*=qwiklabs-gcp-04-331618d6c19' | tr '\0' '\n'

For a more general solution, consider the command

printenv | sort -t = -k 2 | tr = ' ' | uniq -f 1 -D  | sed 's/ /=/'

This will produce on stdout a list of all environment variables, which have the property that two variables have the same value.

The first sort sorts the variables by their value. The tr is necessary, because uniq does not except a field delimiter. uniq shows the duplicates. The sed just puts back the equal sign removed by tr for easier reading.

This works with variables containing spaces, but it breaks if the value of an environment variable contains a newline characters.

for i in `env | cut -d= -f 2- | sort | uniq -d`; do env | grep "$i";done | cut -d= -f1

This will have some issues with variables containing spaces

Related