Issue
The .env.sample files in the projects i work with are always outdated. How would I write a one-liner to recursively search all files in a project and extract the used env variables to a .env.sample file.
The one-liner bash script should ideally match all the following formats
process.env.MY_VAR
process.env.MY-VAR
process.env["MY_VAR"]
process.env['MY_VAR']
process.env[MY_VAR] // MY_VAR here being a constant which holds the actual key value
Find the unique values and print to a sample .env file which could be plugged into a pre-commit hook or pipeline.
Solution
Here is a one-liner which should work
grep -rhoP "process\.env[\.\[](\"|\')?[A-Z0-9_\-]+(\"|\')?[\]]?" ./src \
| sed -r -n 's|^.*\.([[:upper:]0-9_-]+).*$|\1=|p' | sort --unique > .env.sample
Breaking it down
grep -rhoP "process\.env[\.\[](\"|\')?[a-zA-Z0-9_\-]+(\"|\')?[\]]?" ./src
Grep modifiers
-P, --perl-regexp Enables support for PCRE regexp Note: OpenBSD version of grep do not support PCRE expressions, GNU grep required on MacOS -r recursive Read all files under each directory, recursively, following symbolic links only if they are on the command line. -o, --only-matching Print only the matched (non-empty) parts of a matching line, on a separate output line. -h, --no-filename Suppress the prefixing of file names on output
The regex
process\.env[\.\[](\"|\')?[A-Z0-9_\-]+(\"|\')?[\]]?
- Matches the string literal
process.env
[\.\[]
matches the literal "." or "["(\"|\')?
matches single or double quotes optionally[A-Z0-9_\-]+
matches one or more the upper case, numbers , underscores and dashes(\"|\')?
matches single or double quotes optionally[\]]?
matches the literal "]" optionally
- Matches the string literal
sort --unique
we only want distinct values and sorted alphabetically (makes diff comparison easier with consistent ordered list of keys )sed -r -n 's|^.*\.([[:upper:]0-9_]+).*$|\1=|p'
- shorter version of the previous regex matching all upper case characters , numbers, dashes after the literal "s." or starting with "."
- inserts a "=" and prints the output silently
Note This is not a foolproof or comprehensive by any means . For example it does not match small case environment variables or plenty of other methods of access for example object deconstruction like const { MY_VAR } = process.env
Answered By - Manquer Answer Checked By - Cary Denson (WPSolving Admin)