Skip to main content

Compare environment files in the Linux console

Struggling to sync your .env and .env.example files? Learn a powerful Linux CLI command using diff, grep, and sort to accurately compare environment variables and skip comments.

· 5 min read
View raw
Christophe
Markdown, WSL and Docker lover ~ Insatiable curious.
Cet article existe aussi en français — lire la version française.

This article is over a year old but was reviewed on July 30, 2026 — the content is still accurate.

Compare environment files in the Linux console

⚡
TL;DR

This article shows a Linux one-liner to reliably compare two .env files (e.g. .env vs .env.example) using diff -y --suppress-common-lines combined with grep and sort, so comments, blank lines, and line order are ignored and specific variables (like APP_KEY) can be excluded from the comparison.

This is a very common source of problems using .env files: you have two or more different .env files like .env and .env.example.

You're a programmer and coding a new amazing feature. You're adding one or more new environment variables to your local .env file and everything is working fine on your computer.

Boum! Your feature is buggy.

A colleague copies the source code from a version-control system like GitHub/GitLab, or, second scenario, someone deploys the feature to a server — and your feature breaks.

Why? Because the variable(s) you've added have been added in your local .env file, on your computer only.

As you know, you have to create the variables in the .env.example file too but let's be honest, nobody thinks about it.

The one-liner and its output​

Copy this in your console, in the folder holding the two files:

(
clear
ENV1=.env
ENV2=.env.example
printf "\e[33;1m%-63s %s\e[0;1m\n" "Left side: ${ENV1}" "Right side: ${ENV2}"
diff --suppress-common-lines -y \
<(grep -v -E '^#|^$' ${ENV1}| sort) \
<(grep -v -E '^#|^$' ${ENV2} | sort) \
| grep -v 'APP_KEY'
)

On two .env files that have drifted apart, here is what comes back:

Left side: .env Right side: .env.example
ALLOW_FEATURE_DO_THIS = true <
DATABASE_TYPE = pgsql | CACHE_DRIVER = redis
> DATABASE_TYPE = mysql

How to read:

  • ALLOW_FEATURE_DO_THIS is only present in .env,
  • DATABASE_TYPE is initialized to pgsql in .env and to mysql in .env.example,
  • CACHE_DRIVER is only present in .env.example and
  • all other lines are strictly identical (remember we've ignored commented and empty lines)

Three lines of output, and the answer to "what did I forget to report in .env.example?" is right there.

Why plain diff isn't enough​

diff alone (see Linux - Comparing two folders/files in the console for the general case) would drown you in noise, because:

  1. We don't care about comments and empty lines. If a variable has been commented, we just need to ignore it.
  2. We don't care about the position in the file where the variable is declared. If APP_ENV = local is on the first line, in the middle of the file or just before the last line, we don't care about it.
  3. We can also ignore some variables that we know should be different, like APP_KEY f.i.

That's exactly what the three helpers around diff are doing: grep -v -E '^#|^$' drops comments and blank lines, sort neutralizes the order, and the final grep -v 'APP_KEY' removes the variables you already know will differ.

The flag --suppress-common-lines -y does the rest: display the result in two columns (-y) and only the differences (--suppress-common-lines).

Reproduce it​

Let's try... Below we'll create the file .env.example with two lines then copy it to .env and just add a new line in .env.example. Finally, we'll sort .env.example so the order will differ with .env.

>user@machine: ~/yourproject

Now that we have our two files with one single difference, running the command above gives:

Left side: .env Right side: .env.example
> CACHE_DRIVER = redis

The column on the left represents the first file (in our example .env) while the column on the right is for the second file (.env.example). So: CACHE_DRIVER exists only in .env.example.

For the illustration, we can now add a new key but just in .env (real world situation: I'm coding a new feature and I add a variable like a switch on/off)

>user@machine: ~/yourproject

Now the output will be:

Left side: .env Right side: .env.example
ALLOW_FEATURE_DO_THIS = true <
> CACHE_DRIVER = redis

Last sample, the same key with two different values on each side:

>user@machine: ~/yourproject

And you're back to the three-line output shown at the top of this article, where the | marker appears: same key, different values.

Conclusion​

Nobody thinks about updating .env.example — that's the whole problem, and no amount of good intentions fixes it. A one-liner you can paste before every commit does, because it takes two seconds and answers with three lines or nothing at all.

Once you know which keys are missing, the next step is to add them everywhere without editing each file by hand: Batch edit of environment file. And to consume those variables from your scripts, see Bash - Loading environment variables from a file.


Was this article helpful?
Did you try the steps in this article?