Reputation: 1153
I've got the following AWK
script I'm using to update settings.py
.
I utilising during Docker install and I'm trying to pass ENV variables.
ENV variables to pass:
DB_USER,
DB_PASS,
DB_NAME
The code below
awk 'function pr(sp, k, v){ # prints key-value pair with indentation
printf "%s\047%s\047: \047%s\047,\n",sp,k,v;
}
/sqlite/{ sub(/sqlite[0-9]*/,"mysql",$0) }
/NAME/{ sp=substr($0,1,index($0,"\047")-1);
print sp$1" \047$DB_NAME\047";
pr(sp,"USER","$DB_USER"); pr(sp,"PASSWORD","$DB_PASS");
pr(sp,"HOST","localhost"); pr(sp,"PORT",""); next
}1'
Upvotes: 9
Views: 8470
Reputation: 85800
You can use the ENVIRON
variable in GNU Awk
,
From the GNU Awk man
page,
ENVIRON
An associative array containing the values of the environment. The array indices are the environment variable names; the elements are the values of the particular environment variables. For example,
ENVIRON["HOME"]
might be"/home/arnold"
. Changing this array does not affect the environment passed on to any programs thatawk
may spawn via redirection or thesystem()
function. (In a future version ofgawk
, it may do so.)
Using the above array to reference your environment variables, just do this in the BEGIN
clause to load all the variables and use it later
awk 'BEGIN {
db_user = ENVIRON["DB_USER"]
db_pass = ENVIRON["DB_PASS"]
db_name = ENVIRON["DB_NAME"]
}'
Use the variables db_user
, db_pass
and db_name
in the body of the Awk
as you wish. By importing the environment variables in BEGIN
, you don't have to import them once for each line in the input file.
Upvotes: 13
Reputation: 8741
There are actually two more ways, aside from ENVIRON
, to get shell variables into awk programs, according to the documentation. This is especially useful when using local shell variables as ENVIRON
works only for exported or environment variables.
There is a gotcha when trying to use variables as patterns so I will use them as patterns in our examples.
So lets say we want to get the current user's home directory from /etc/passwd
, the separator is :
so we need to tell awk about that by using the -F
argument.
Without using variables we would write the simple program like this:
$ awk -F: '$1~/nickl/ {print $6}' /etc/passwd
/home/nickl
But instead we want to use the environment variable $USER
.
We can separate the awk program string by supplying both single and double quoted strings without spaces in between, the latter will of course allow for variable substitution where as the former ignores the $
used by awk to denote field numbers.
$ awk -F: '$1~'"/$USER/ "'{print $6}' /etc/passwd
/home/nickl
The previous method could get confusing and land you into trouble trying to keep track of separated strings, especially with more complex programs, so instead we can use command line variable assignment with the -v
option.
$ awk -F: -v var=$USER '$1~var {print $6}' /etc/passwd
/home/nickl
Note: You would probably want to put the variable into quotes "$USER"
if there is any chance that it might contain spaces.
As per the accepted answer, the third option is to use the built-in variable ENVIRON
. You may have noticed from the previous method that we are not using regexp constant, by excluding the slashes //
from the pattern. The gotcha is when using awk variables in patterns we use dynamic regexps instead, without the slashes.
$ awk -F: '$1~ENVIRON["USER"] {print $6}' /etc/passwd
/home/nickl
EDIT: As pointed out by @RAREKpopManifesto, if directly declared we can pass local variables to be accessible by ENVIRON
, even without changing an exported variable.
$ LOCAL_USER="rarek"
$ USER="$LOCAL_USER" awk -F: '$1~ENVIRON["USER"] {print $6}' /etc/passwd
/home/rarek
$ echo $USER
nickl
nJoy!
Upvotes: 2