I have a .env file,
# Some variables
USERNAME=user1
PASSWORD=
# Other variables
URL=https://example.com
TOKEN=muDm8qJ6mqM__YX024dk1RXluPnwd-3mxyt1LwLoI4ISiVPA==
Purpose
My purpose is to create one line bash command to print each non-empty variables in <name> <value> format, which shall
- Print one line for each variable with [space] between name and value;
- Ignore comments;
- Ignore variables with no value;
Expected output
The expected output is,
USERNAME user1
URL https://example.com
TOKEN muDm8qJ6mqM__YX024dk1RXluPnwd-3mxyt1LwLoI4ISiVPA==
Current Solution
My current solution is as following,
grep -v '^#' .env | grep -v '^[[:space:]]*$' | grep -v '=$' | sed 's/=/ /' | while read -r line; do echo $line; done
Actual output
USERNAME user1
URL https://example.com
It only prints out the first two lines, the issue with last line is caused by the equal (=) signs in TOKEN value.
Help needed
Anyone can help me to rectify the command? also welcome if there is easier way to achieve the goal.
CodePudding user response:
The only way to process any environment variable file is to actually interpret it. Various methods for printing out the variable lists are described below.
Various “environment files” are usually designed to be run by POSIX shell to evaluate all the variables. That makes it possible to call external commands, perform calculations etc. when assigning to the variables.
Do this only is you trust you input file. Any command can be executed by parsing the file using the script below.
You can source the file (builtin command .):
. .env
After you source it, you can evaluate the variables. If you know what all variables you want to print, use this (for vars USERNAME and PASSWORD)
. .env
for var_name in USERNAME PASSWORD
do
printf "%s %s\n" "$var_name" "${!var_name}"
done
If you want to print all the variables that are explicitly specified, use this approach:
. .env
grep '^\w =' | sed 's/=//' | while read var_name
do
printf "%s %s\n" "$var_name" "${!var_name}"
done
But this solution is also not perfect, because the .env file can use constructions different from var_name=value to assign the vars. Use the set command to print all variables.
This prints out absolutely all variables. (In reality, the environment file should inherit its variables from the system environment vars, so there is a lot of them.)
. .env
printenv | sed 's/=/ /'
The sed is used to get rid of the equals signs.
Beware of some dangerous variable values. The variables can contain even newline character, backspaces and other control characters.
There is also a lot of various utilities for printing the variable in a way that allow loading them back to the shell. For example:
declare -p or typeset -p — prints out declare commands to declare all the currently set shell variables
export -p — the same, but for environment variables (that is probably that thing you want)
set — prints out all shell variables
CodePudding user response:
Using sed
$ sed '/#\|^$/d;/=\</!d;s/=/ /' input_file
USERNAME user1
URL https://example.com
TOKEN muDm8qJ6mqM__YX024dk1RXluPnwd-3mxyt1LwLoI4ISiVPA==
CodePudding user response:
If the file contains only comments and simple key=value lines without # chars in strings, you can use this pipeline:
sed 's/#.*//' | fgrep = | sed 's/=/ /'
