I found some ways to pass external shell variables to an awk
script, but I'm confused about '
and "
.
First, I tried with a shell script:
$ v=123test
$ echo $v
123test
$ echo "$v"
123test
Then tried awk:
$ awk 'BEGIN{print "'$v'"}'
$ 123test
$ awk 'BEGIN{print '"$v"'}'
$ 123
Why is the difference?
Lastly I tried this:
$ awk 'BEGIN{print " '$v' "}'
$ 123test
$ awk 'BEGIN{print ' "$v" '}'
awk: cmd. line:1: BEGIN{print
awk: cmd. line:1: ^ unexpected newline or end of string
I'm confused about this.
Getting shell variables into
awk
may be done in several ways. Some are better than others.This is the best way to do it. It uses the
-v
option: (P.S. use a space after-v
or it will be less portable. E.g.,awk -v var=
notawk -vvar=
)This should be compatible with most
awk
and variable is available in theBEGIN
block as well:Multiple variables
Here we get the variable after the
awk
code. This will work fine as long as you do not need the variable in theBEGIN
block:This also works with multiple variables
awk '{print a,b,$0}' a="$var1" b="$var2" file
Variable can also be added to
awk
using here stringThis is the same as:
PS, this threats the variable as a file input
As TrueY write, you can use the
ENVIRON
to printEnvironmental Variables
Setting a variable before running AWK, you can print it out like this:Edit: As "that other guy" write, this does not handle backslash. Not recommended.
You can use a variable within the
awk
code, but it's messy and hard to read, and asCharles Duffy
points out, this version may also be a victim of code injection. If someone adds bad stuff to the variable, it will be executed as part of theawk
code.If you want to make an
awk
that changes dynamically with use of variables, you can do it this way, bot DO NOT use it for normal variables.Here is an example of code injection:
You can add lots of commands to
awk
this way. Even make it crash with non valid commands.It's always good to double quote variable
"$variable"
If not, multiple lines will be added as a long single line.
Example:
Other errors you can get without double quote:
And with single quote, it does not expand the value of the variable:
You could pass in the command-line option
-v
with a variable name (v
) and a value (=
) of the environment variable ("${v}"
):Or to make it clearer (with far fewer
v
s):You can utilize ARGV:
Note that if you are going to continue into the body, you will need to adjust ARGC:
I had to insert date at the beginning of the lines of a log file and it's done like below:
It can be redirect to another file to save
Use either of these depending how you want backslashes in the shell variables handled (
avar
is an awk variable,svar
is a shell variable):See http://cfajohnson.com/shell/cus-faq-2.html#Q24 for details and other options. The first method above is almost always your best option and has the most obvious semantics.