How do I use shell variables in an awk script?
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.
bash shell awk
add a comment |
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.
bash shell awk
1
I like the -v as shown below, but this is really a great exercise in thinking about how to protect things from the shell. Working through this, my first cut use backslashes on spaces and dollar signs. Needless to say the examples here were well worth my time.
– Chris
Dec 20 '16 at 21:00
Related: Difference between single and double quotes in awk.
– codeforester
May 11 '18 at 18:45
add a comment |
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.
bash shell awk
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.
bash shell awk
bash shell awk
edited Sep 3 '18 at 19:41
codeforester
18.7k84267
18.7k84267
asked Sep 29 '13 at 7:45
hqjmahqjma
1,083285
1,083285
1
I like the -v as shown below, but this is really a great exercise in thinking about how to protect things from the shell. Working through this, my first cut use backslashes on spaces and dollar signs. Needless to say the examples here were well worth my time.
– Chris
Dec 20 '16 at 21:00
Related: Difference between single and double quotes in awk.
– codeforester
May 11 '18 at 18:45
add a comment |
1
I like the -v as shown below, but this is really a great exercise in thinking about how to protect things from the shell. Working through this, my first cut use backslashes on spaces and dollar signs. Needless to say the examples here were well worth my time.
– Chris
Dec 20 '16 at 21:00
Related: Difference between single and double quotes in awk.
– codeforester
May 11 '18 at 18:45
1
1
I like the -v as shown below, but this is really a great exercise in thinking about how to protect things from the shell. Working through this, my first cut use backslashes on spaces and dollar signs. Needless to say the examples here were well worth my time.
– Chris
Dec 20 '16 at 21:00
I like the -v as shown below, but this is really a great exercise in thinking about how to protect things from the shell. Working through this, my first cut use backslashes on spaces and dollar signs. Needless to say the examples here were well worth my time.
– Chris
Dec 20 '16 at 21:00
Related: Difference between single and double quotes in awk.
– codeforester
May 11 '18 at 18:45
Related: Difference between single and double quotes in awk.
– codeforester
May 11 '18 at 18:45
add a comment |
8 Answers
8
active
oldest
votes
Getting shell variables into awk
may be done in several ways. Some are better than others. This should cover most of them. If you have a comment, please leave below.
Using -v
(The best way, most portable)
Use the -v
option: (P.S. use a space after -v
or it will be less portable. E.g., awk -v var=
not awk -vvar=
)
variable="line onenline two"
awk -v var="$variable" 'BEGIN {print var}'
line one
line two
This should be compatible with most awk
, and the variable is available in the BEGIN
block as well:
If you have multiple variables:
awk -v a="$var1" -v b="$var2" 'BEGIN {print a,b}'
Warning. As Ed Morton writes, escape sequences will be interpreted so t
becomes a real tab
and not t
if that is what you search for. Can be solved by using ENVIRON
or access it via ARGV
Variable after code block
Here we get the variable after the awk
code. This will work fine as long as you do not need the variable in the BEGIN
block:
variable="line onenline two"
echo "input data" | awk '{print var}' var="${variable}"
or
awk '{print var}' var="${variable}" file
This also works with multiple variables
awk '{print a,b,$0}' a="$var1" b="$var2" file
Using variable this way does not work in BEGIN
block:
echo "input data" | awk 'BEGIN {print var}' var="${variable}"
Here-string
Variable can also be added to awk
using a here-string from shells that support them (including Bash):
awk '{print $0}' <<< "$variable"
test
This is the same as:
printf '%s' "$variable" | awk '{print $0}'
P.S. this treats the variable as a file input.
ENVIRON
input
As TrueY writes, you can use the ENVIRON
to print Environment Variables.
Setting a variable before running AWK, you can print it out like this:
X=MyVar awk 'BEGIN{print ENVIRON["X"],ENVIRON["SHELL"]}'
MyVar /bin/bash
ARGV
input
As Steven Penny writes, you can use ARGV
to get the data into awk:
v="my data"
awk 'BEGIN {print ARGV[1]}' "$v"
my data
To get the data into the code itself, not just the BEGIN:
v="my data"
echo "test" | awk 'BEGIN{var=ARGV[1];ARGV[1]=""} {print var, $0}' "$v"
my data test
Variable within the code: USE WITH CAUTION
You can use a variable within the awk
code, but it's messy and hard to read, and as Charles 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 the awk
code.
This works by extracting the variable within the code, so it becomes a part of it.
If you want to make an awk
that changes dynamically with use of variables, you can do it this way, but DO NOT use it for normal variables.
variable="line onenline two"
awk 'BEGIN {print "'"$variable"'"}'
line one
line two
Here is an example of code injection:
variable='line onenline two" ; for (i=1;i<=1000;++i) print i"'
awk 'BEGIN {print "'"$variable"'"}'
line one
line two
1
2
3
.
.
1000
You can add lots of commands to awk
this way. Even make it crash with non valid commands.
Extra info:
Use of double quote
It's always good to double quote variable "$variable"
If not, multiple lines will be added as a long single line.
Example:
var="Line one
This is line two"
echo $var
Line one This is line two
echo "$var"
Line one
This is line two
Other errors you can get without double quote:
variable="line onenline two"
awk -v var=$variable 'BEGIN {print var}'
awk: cmd. line:1: onenline
awk: cmd. line:1: ^ backslash not last character on line
awk: cmd. line:1: onenline
awk: cmd. line:1: ^ syntax error
And with single quote, it does not expand the value of the variable:
awk -v var='$variable' 'BEGIN {print var}'
$variable
More info about AWK and variables
Read this faq.
1
"messy and hard to read" ignores the more important security concern of code injection when directly substituting strings into awk code.
– Charles Duffy
Feb 18 '16 at 20:21
1
@CharlesDuffy. You are 100% correct. Cleaned up some more.
– Jotne
Feb 18 '16 at 21:07
1
@EdMorton. Thanks for the input. I am on different planet compare to you about this :) Most of this post are made and change due to comments by others. Updated post to reflect your comments.
– Jotne
Feb 16 at 7:15
Just get rid ofEdit: As "that other guy" write, this does not handle backslash. Not recommended.
now - it handles backslash just fine by not interpreting it, and it is one of recommended approaches if/when you need that behavior.
– Ed Morton
Feb 16 at 14:48
add a comment |
It seems that the good-old ENVIRON
awk built-in hash is not mentioned at all. An example of its usage:
$ X=Solaris awk 'BEGIN{print ENVIRON["X"], ENVIRON["TERM"]}'
Solaris rxvt
3
This is a good suggestion because it passes the data verbatim.-v
doesn't work when the value contains backslashes.
– that other guy
Feb 23 '16 at 21:45
1
@thatotherguy I did not know that! I thought that if I useawk -v x='cd' ...
then it will be used it properly. But whenx
is printed awk drops the famous:awk: warning: escape sequence 'c' treated as plain 'c'
error message... Thanks!
– TrueY
Feb 24 '16 at 9:11
add a comment |
Use either of these depending how you want backslashes in the shell variables handled (avar
is an awk variable, svar
is a shell variable):
awk -v avar="$svar" '... avar ...' file
awk 'BEGIN{avar=ARGV[1];ARGV[1]=""}... avar ...' "$svar" file
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.
add a comment |
You could pass in the command-line option -v
with a variable name (v
) and a value (=
) of the environment variable ("${v}"
):
% awk -vv="${v}" 'BEGIN { print v }'
123test
Or to make it clearer (with far fewer v
s):
% environment_variable=123test
% awk -vawk_variable="${environment_variable}" 'BEGIN { print awk_variable }'
123test
add a comment |
You can utilize ARGV:
v=123test
awk 'BEGIN {print ARGV[1]}' "$v"
Note that if you are going to continue into the body, you will need to adjust
ARGC:
awk 'BEGIN {ARGC--} {print ARGV[2], $0}' file "$v"
add a comment |
I had to insert date at the beginning of the lines of a log file and it's done like below:
DATE=$(date +"%Y-%m-%d")
awk '{ print "'"$DATE"'", $0; }' /path_to_log_file/log_file.log
It can be redirect to another file to save
The double quote - single quote - double quote was exactly what I needed to make mine work.
– user53029
Jul 21 '16 at 14:24
This was already mentioned in the accepted answer as a method you should not use due to code injection vulnerabilities. So the information here is redundant (already described in the accepted answer), and incomplete (does not mention the problems with this method).
– Jason S
Oct 12 '16 at 5:20
add a comment |
I just changed @Jotne's answer for "for loop".
for i in `seq 11 20`; do host myserver-$i | awk -v i="$i" '{print "myserver-"i" " $4}'; done
add a comment |
for i in chr{1..22} chrX chrY
do
awk -v chr="$i" '$1==chr' ../snp150.hg19.txt >> $chr.vcf.bed
echo $i
done
add a comment |
protected by Inian Apr 27 '18 at 19:37
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?
8 Answers
8
active
oldest
votes
8 Answers
8
active
oldest
votes
active
oldest
votes
active
oldest
votes
Getting shell variables into awk
may be done in several ways. Some are better than others. This should cover most of them. If you have a comment, please leave below.
Using -v
(The best way, most portable)
Use the -v
option: (P.S. use a space after -v
or it will be less portable. E.g., awk -v var=
not awk -vvar=
)
variable="line onenline two"
awk -v var="$variable" 'BEGIN {print var}'
line one
line two
This should be compatible with most awk
, and the variable is available in the BEGIN
block as well:
If you have multiple variables:
awk -v a="$var1" -v b="$var2" 'BEGIN {print a,b}'
Warning. As Ed Morton writes, escape sequences will be interpreted so t
becomes a real tab
and not t
if that is what you search for. Can be solved by using ENVIRON
or access it via ARGV
Variable after code block
Here we get the variable after the awk
code. This will work fine as long as you do not need the variable in the BEGIN
block:
variable="line onenline two"
echo "input data" | awk '{print var}' var="${variable}"
or
awk '{print var}' var="${variable}" file
This also works with multiple variables
awk '{print a,b,$0}' a="$var1" b="$var2" file
Using variable this way does not work in BEGIN
block:
echo "input data" | awk 'BEGIN {print var}' var="${variable}"
Here-string
Variable can also be added to awk
using a here-string from shells that support them (including Bash):
awk '{print $0}' <<< "$variable"
test
This is the same as:
printf '%s' "$variable" | awk '{print $0}'
P.S. this treats the variable as a file input.
ENVIRON
input
As TrueY writes, you can use the ENVIRON
to print Environment Variables.
Setting a variable before running AWK, you can print it out like this:
X=MyVar awk 'BEGIN{print ENVIRON["X"],ENVIRON["SHELL"]}'
MyVar /bin/bash
ARGV
input
As Steven Penny writes, you can use ARGV
to get the data into awk:
v="my data"
awk 'BEGIN {print ARGV[1]}' "$v"
my data
To get the data into the code itself, not just the BEGIN:
v="my data"
echo "test" | awk 'BEGIN{var=ARGV[1];ARGV[1]=""} {print var, $0}' "$v"
my data test
Variable within the code: USE WITH CAUTION
You can use a variable within the awk
code, but it's messy and hard to read, and as Charles 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 the awk
code.
This works by extracting the variable within the code, so it becomes a part of it.
If you want to make an awk
that changes dynamically with use of variables, you can do it this way, but DO NOT use it for normal variables.
variable="line onenline two"
awk 'BEGIN {print "'"$variable"'"}'
line one
line two
Here is an example of code injection:
variable='line onenline two" ; for (i=1;i<=1000;++i) print i"'
awk 'BEGIN {print "'"$variable"'"}'
line one
line two
1
2
3
.
.
1000
You can add lots of commands to awk
this way. Even make it crash with non valid commands.
Extra info:
Use of double quote
It's always good to double quote variable "$variable"
If not, multiple lines will be added as a long single line.
Example:
var="Line one
This is line two"
echo $var
Line one This is line two
echo "$var"
Line one
This is line two
Other errors you can get without double quote:
variable="line onenline two"
awk -v var=$variable 'BEGIN {print var}'
awk: cmd. line:1: onenline
awk: cmd. line:1: ^ backslash not last character on line
awk: cmd. line:1: onenline
awk: cmd. line:1: ^ syntax error
And with single quote, it does not expand the value of the variable:
awk -v var='$variable' 'BEGIN {print var}'
$variable
More info about AWK and variables
Read this faq.
1
"messy and hard to read" ignores the more important security concern of code injection when directly substituting strings into awk code.
– Charles Duffy
Feb 18 '16 at 20:21
1
@CharlesDuffy. You are 100% correct. Cleaned up some more.
– Jotne
Feb 18 '16 at 21:07
1
@EdMorton. Thanks for the input. I am on different planet compare to you about this :) Most of this post are made and change due to comments by others. Updated post to reflect your comments.
– Jotne
Feb 16 at 7:15
Just get rid ofEdit: As "that other guy" write, this does not handle backslash. Not recommended.
now - it handles backslash just fine by not interpreting it, and it is one of recommended approaches if/when you need that behavior.
– Ed Morton
Feb 16 at 14:48
add a comment |
Getting shell variables into awk
may be done in several ways. Some are better than others. This should cover most of them. If you have a comment, please leave below.
Using -v
(The best way, most portable)
Use the -v
option: (P.S. use a space after -v
or it will be less portable. E.g., awk -v var=
not awk -vvar=
)
variable="line onenline two"
awk -v var="$variable" 'BEGIN {print var}'
line one
line two
This should be compatible with most awk
, and the variable is available in the BEGIN
block as well:
If you have multiple variables:
awk -v a="$var1" -v b="$var2" 'BEGIN {print a,b}'
Warning. As Ed Morton writes, escape sequences will be interpreted so t
becomes a real tab
and not t
if that is what you search for. Can be solved by using ENVIRON
or access it via ARGV
Variable after code block
Here we get the variable after the awk
code. This will work fine as long as you do not need the variable in the BEGIN
block:
variable="line onenline two"
echo "input data" | awk '{print var}' var="${variable}"
or
awk '{print var}' var="${variable}" file
This also works with multiple variables
awk '{print a,b,$0}' a="$var1" b="$var2" file
Using variable this way does not work in BEGIN
block:
echo "input data" | awk 'BEGIN {print var}' var="${variable}"
Here-string
Variable can also be added to awk
using a here-string from shells that support them (including Bash):
awk '{print $0}' <<< "$variable"
test
This is the same as:
printf '%s' "$variable" | awk '{print $0}'
P.S. this treats the variable as a file input.
ENVIRON
input
As TrueY writes, you can use the ENVIRON
to print Environment Variables.
Setting a variable before running AWK, you can print it out like this:
X=MyVar awk 'BEGIN{print ENVIRON["X"],ENVIRON["SHELL"]}'
MyVar /bin/bash
ARGV
input
As Steven Penny writes, you can use ARGV
to get the data into awk:
v="my data"
awk 'BEGIN {print ARGV[1]}' "$v"
my data
To get the data into the code itself, not just the BEGIN:
v="my data"
echo "test" | awk 'BEGIN{var=ARGV[1];ARGV[1]=""} {print var, $0}' "$v"
my data test
Variable within the code: USE WITH CAUTION
You can use a variable within the awk
code, but it's messy and hard to read, and as Charles 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 the awk
code.
This works by extracting the variable within the code, so it becomes a part of it.
If you want to make an awk
that changes dynamically with use of variables, you can do it this way, but DO NOT use it for normal variables.
variable="line onenline two"
awk 'BEGIN {print "'"$variable"'"}'
line one
line two
Here is an example of code injection:
variable='line onenline two" ; for (i=1;i<=1000;++i) print i"'
awk 'BEGIN {print "'"$variable"'"}'
line one
line two
1
2
3
.
.
1000
You can add lots of commands to awk
this way. Even make it crash with non valid commands.
Extra info:
Use of double quote
It's always good to double quote variable "$variable"
If not, multiple lines will be added as a long single line.
Example:
var="Line one
This is line two"
echo $var
Line one This is line two
echo "$var"
Line one
This is line two
Other errors you can get without double quote:
variable="line onenline two"
awk -v var=$variable 'BEGIN {print var}'
awk: cmd. line:1: onenline
awk: cmd. line:1: ^ backslash not last character on line
awk: cmd. line:1: onenline
awk: cmd. line:1: ^ syntax error
And with single quote, it does not expand the value of the variable:
awk -v var='$variable' 'BEGIN {print var}'
$variable
More info about AWK and variables
Read this faq.
1
"messy and hard to read" ignores the more important security concern of code injection when directly substituting strings into awk code.
– Charles Duffy
Feb 18 '16 at 20:21
1
@CharlesDuffy. You are 100% correct. Cleaned up some more.
– Jotne
Feb 18 '16 at 21:07
1
@EdMorton. Thanks for the input. I am on different planet compare to you about this :) Most of this post are made and change due to comments by others. Updated post to reflect your comments.
– Jotne
Feb 16 at 7:15
Just get rid ofEdit: As "that other guy" write, this does not handle backslash. Not recommended.
now - it handles backslash just fine by not interpreting it, and it is one of recommended approaches if/when you need that behavior.
– Ed Morton
Feb 16 at 14:48
add a comment |
Getting shell variables into awk
may be done in several ways. Some are better than others. This should cover most of them. If you have a comment, please leave below.
Using -v
(The best way, most portable)
Use the -v
option: (P.S. use a space after -v
or it will be less portable. E.g., awk -v var=
not awk -vvar=
)
variable="line onenline two"
awk -v var="$variable" 'BEGIN {print var}'
line one
line two
This should be compatible with most awk
, and the variable is available in the BEGIN
block as well:
If you have multiple variables:
awk -v a="$var1" -v b="$var2" 'BEGIN {print a,b}'
Warning. As Ed Morton writes, escape sequences will be interpreted so t
becomes a real tab
and not t
if that is what you search for. Can be solved by using ENVIRON
or access it via ARGV
Variable after code block
Here we get the variable after the awk
code. This will work fine as long as you do not need the variable in the BEGIN
block:
variable="line onenline two"
echo "input data" | awk '{print var}' var="${variable}"
or
awk '{print var}' var="${variable}" file
This also works with multiple variables
awk '{print a,b,$0}' a="$var1" b="$var2" file
Using variable this way does not work in BEGIN
block:
echo "input data" | awk 'BEGIN {print var}' var="${variable}"
Here-string
Variable can also be added to awk
using a here-string from shells that support them (including Bash):
awk '{print $0}' <<< "$variable"
test
This is the same as:
printf '%s' "$variable" | awk '{print $0}'
P.S. this treats the variable as a file input.
ENVIRON
input
As TrueY writes, you can use the ENVIRON
to print Environment Variables.
Setting a variable before running AWK, you can print it out like this:
X=MyVar awk 'BEGIN{print ENVIRON["X"],ENVIRON["SHELL"]}'
MyVar /bin/bash
ARGV
input
As Steven Penny writes, you can use ARGV
to get the data into awk:
v="my data"
awk 'BEGIN {print ARGV[1]}' "$v"
my data
To get the data into the code itself, not just the BEGIN:
v="my data"
echo "test" | awk 'BEGIN{var=ARGV[1];ARGV[1]=""} {print var, $0}' "$v"
my data test
Variable within the code: USE WITH CAUTION
You can use a variable within the awk
code, but it's messy and hard to read, and as Charles 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 the awk
code.
This works by extracting the variable within the code, so it becomes a part of it.
If you want to make an awk
that changes dynamically with use of variables, you can do it this way, but DO NOT use it for normal variables.
variable="line onenline two"
awk 'BEGIN {print "'"$variable"'"}'
line one
line two
Here is an example of code injection:
variable='line onenline two" ; for (i=1;i<=1000;++i) print i"'
awk 'BEGIN {print "'"$variable"'"}'
line one
line two
1
2
3
.
.
1000
You can add lots of commands to awk
this way. Even make it crash with non valid commands.
Extra info:
Use of double quote
It's always good to double quote variable "$variable"
If not, multiple lines will be added as a long single line.
Example:
var="Line one
This is line two"
echo $var
Line one This is line two
echo "$var"
Line one
This is line two
Other errors you can get without double quote:
variable="line onenline two"
awk -v var=$variable 'BEGIN {print var}'
awk: cmd. line:1: onenline
awk: cmd. line:1: ^ backslash not last character on line
awk: cmd. line:1: onenline
awk: cmd. line:1: ^ syntax error
And with single quote, it does not expand the value of the variable:
awk -v var='$variable' 'BEGIN {print var}'
$variable
More info about AWK and variables
Read this faq.
Getting shell variables into awk
may be done in several ways. Some are better than others. This should cover most of them. If you have a comment, please leave below.
Using -v
(The best way, most portable)
Use the -v
option: (P.S. use a space after -v
or it will be less portable. E.g., awk -v var=
not awk -vvar=
)
variable="line onenline two"
awk -v var="$variable" 'BEGIN {print var}'
line one
line two
This should be compatible with most awk
, and the variable is available in the BEGIN
block as well:
If you have multiple variables:
awk -v a="$var1" -v b="$var2" 'BEGIN {print a,b}'
Warning. As Ed Morton writes, escape sequences will be interpreted so t
becomes a real tab
and not t
if that is what you search for. Can be solved by using ENVIRON
or access it via ARGV
Variable after code block
Here we get the variable after the awk
code. This will work fine as long as you do not need the variable in the BEGIN
block:
variable="line onenline two"
echo "input data" | awk '{print var}' var="${variable}"
or
awk '{print var}' var="${variable}" file
This also works with multiple variables
awk '{print a,b,$0}' a="$var1" b="$var2" file
Using variable this way does not work in BEGIN
block:
echo "input data" | awk 'BEGIN {print var}' var="${variable}"
Here-string
Variable can also be added to awk
using a here-string from shells that support them (including Bash):
awk '{print $0}' <<< "$variable"
test
This is the same as:
printf '%s' "$variable" | awk '{print $0}'
P.S. this treats the variable as a file input.
ENVIRON
input
As TrueY writes, you can use the ENVIRON
to print Environment Variables.
Setting a variable before running AWK, you can print it out like this:
X=MyVar awk 'BEGIN{print ENVIRON["X"],ENVIRON["SHELL"]}'
MyVar /bin/bash
ARGV
input
As Steven Penny writes, you can use ARGV
to get the data into awk:
v="my data"
awk 'BEGIN {print ARGV[1]}' "$v"
my data
To get the data into the code itself, not just the BEGIN:
v="my data"
echo "test" | awk 'BEGIN{var=ARGV[1];ARGV[1]=""} {print var, $0}' "$v"
my data test
Variable within the code: USE WITH CAUTION
You can use a variable within the awk
code, but it's messy and hard to read, and as Charles 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 the awk
code.
This works by extracting the variable within the code, so it becomes a part of it.
If you want to make an awk
that changes dynamically with use of variables, you can do it this way, but DO NOT use it for normal variables.
variable="line onenline two"
awk 'BEGIN {print "'"$variable"'"}'
line one
line two
Here is an example of code injection:
variable='line onenline two" ; for (i=1;i<=1000;++i) print i"'
awk 'BEGIN {print "'"$variable"'"}'
line one
line two
1
2
3
.
.
1000
You can add lots of commands to awk
this way. Even make it crash with non valid commands.
Extra info:
Use of double quote
It's always good to double quote variable "$variable"
If not, multiple lines will be added as a long single line.
Example:
var="Line one
This is line two"
echo $var
Line one This is line two
echo "$var"
Line one
This is line two
Other errors you can get without double quote:
variable="line onenline two"
awk -v var=$variable 'BEGIN {print var}'
awk: cmd. line:1: onenline
awk: cmd. line:1: ^ backslash not last character on line
awk: cmd. line:1: onenline
awk: cmd. line:1: ^ syntax error
And with single quote, it does not expand the value of the variable:
awk -v var='$variable' 'BEGIN {print var}'
$variable
More info about AWK and variables
Read this faq.
edited Mar 13 at 12:00
Toby Speight
17.4k134368
17.4k134368
answered Sep 29 '13 at 7:51
JotneJotne
29.9k83345
29.9k83345
1
"messy and hard to read" ignores the more important security concern of code injection when directly substituting strings into awk code.
– Charles Duffy
Feb 18 '16 at 20:21
1
@CharlesDuffy. You are 100% correct. Cleaned up some more.
– Jotne
Feb 18 '16 at 21:07
1
@EdMorton. Thanks for the input. I am on different planet compare to you about this :) Most of this post are made and change due to comments by others. Updated post to reflect your comments.
– Jotne
Feb 16 at 7:15
Just get rid ofEdit: As "that other guy" write, this does not handle backslash. Not recommended.
now - it handles backslash just fine by not interpreting it, and it is one of recommended approaches if/when you need that behavior.
– Ed Morton
Feb 16 at 14:48
add a comment |
1
"messy and hard to read" ignores the more important security concern of code injection when directly substituting strings into awk code.
– Charles Duffy
Feb 18 '16 at 20:21
1
@CharlesDuffy. You are 100% correct. Cleaned up some more.
– Jotne
Feb 18 '16 at 21:07
1
@EdMorton. Thanks for the input. I am on different planet compare to you about this :) Most of this post are made and change due to comments by others. Updated post to reflect your comments.
– Jotne
Feb 16 at 7:15
Just get rid ofEdit: As "that other guy" write, this does not handle backslash. Not recommended.
now - it handles backslash just fine by not interpreting it, and it is one of recommended approaches if/when you need that behavior.
– Ed Morton
Feb 16 at 14:48
1
1
"messy and hard to read" ignores the more important security concern of code injection when directly substituting strings into awk code.
– Charles Duffy
Feb 18 '16 at 20:21
"messy and hard to read" ignores the more important security concern of code injection when directly substituting strings into awk code.
– Charles Duffy
Feb 18 '16 at 20:21
1
1
@CharlesDuffy. You are 100% correct. Cleaned up some more.
– Jotne
Feb 18 '16 at 21:07
@CharlesDuffy. You are 100% correct. Cleaned up some more.
– Jotne
Feb 18 '16 at 21:07
1
1
@EdMorton. Thanks for the input. I am on different planet compare to you about this :) Most of this post are made and change due to comments by others. Updated post to reflect your comments.
– Jotne
Feb 16 at 7:15
@EdMorton. Thanks for the input. I am on different planet compare to you about this :) Most of this post are made and change due to comments by others. Updated post to reflect your comments.
– Jotne
Feb 16 at 7:15
Just get rid of
Edit: As "that other guy" write, this does not handle backslash. Not recommended.
now - it handles backslash just fine by not interpreting it, and it is one of recommended approaches if/when you need that behavior.– Ed Morton
Feb 16 at 14:48
Just get rid of
Edit: As "that other guy" write, this does not handle backslash. Not recommended.
now - it handles backslash just fine by not interpreting it, and it is one of recommended approaches if/when you need that behavior.– Ed Morton
Feb 16 at 14:48
add a comment |
It seems that the good-old ENVIRON
awk built-in hash is not mentioned at all. An example of its usage:
$ X=Solaris awk 'BEGIN{print ENVIRON["X"], ENVIRON["TERM"]}'
Solaris rxvt
3
This is a good suggestion because it passes the data verbatim.-v
doesn't work when the value contains backslashes.
– that other guy
Feb 23 '16 at 21:45
1
@thatotherguy I did not know that! I thought that if I useawk -v x='cd' ...
then it will be used it properly. But whenx
is printed awk drops the famous:awk: warning: escape sequence 'c' treated as plain 'c'
error message... Thanks!
– TrueY
Feb 24 '16 at 9:11
add a comment |
It seems that the good-old ENVIRON
awk built-in hash is not mentioned at all. An example of its usage:
$ X=Solaris awk 'BEGIN{print ENVIRON["X"], ENVIRON["TERM"]}'
Solaris rxvt
3
This is a good suggestion because it passes the data verbatim.-v
doesn't work when the value contains backslashes.
– that other guy
Feb 23 '16 at 21:45
1
@thatotherguy I did not know that! I thought that if I useawk -v x='cd' ...
then it will be used it properly. But whenx
is printed awk drops the famous:awk: warning: escape sequence 'c' treated as plain 'c'
error message... Thanks!
– TrueY
Feb 24 '16 at 9:11
add a comment |
It seems that the good-old ENVIRON
awk built-in hash is not mentioned at all. An example of its usage:
$ X=Solaris awk 'BEGIN{print ENVIRON["X"], ENVIRON["TERM"]}'
Solaris rxvt
It seems that the good-old ENVIRON
awk built-in hash is not mentioned at all. An example of its usage:
$ X=Solaris awk 'BEGIN{print ENVIRON["X"], ENVIRON["TERM"]}'
Solaris rxvt
answered Nov 6 '14 at 12:46
TrueYTrueY
5,95912839
5,95912839
3
This is a good suggestion because it passes the data verbatim.-v
doesn't work when the value contains backslashes.
– that other guy
Feb 23 '16 at 21:45
1
@thatotherguy I did not know that! I thought that if I useawk -v x='cd' ...
then it will be used it properly. But whenx
is printed awk drops the famous:awk: warning: escape sequence 'c' treated as plain 'c'
error message... Thanks!
– TrueY
Feb 24 '16 at 9:11
add a comment |
3
This is a good suggestion because it passes the data verbatim.-v
doesn't work when the value contains backslashes.
– that other guy
Feb 23 '16 at 21:45
1
@thatotherguy I did not know that! I thought that if I useawk -v x='cd' ...
then it will be used it properly. But whenx
is printed awk drops the famous:awk: warning: escape sequence 'c' treated as plain 'c'
error message... Thanks!
– TrueY
Feb 24 '16 at 9:11
3
3
This is a good suggestion because it passes the data verbatim.
-v
doesn't work when the value contains backslashes.– that other guy
Feb 23 '16 at 21:45
This is a good suggestion because it passes the data verbatim.
-v
doesn't work when the value contains backslashes.– that other guy
Feb 23 '16 at 21:45
1
1
@thatotherguy I did not know that! I thought that if I use
awk -v x='cd' ...
then it will be used it properly. But when x
is printed awk drops the famous: awk: warning: escape sequence 'c' treated as plain 'c'
error message... Thanks!– TrueY
Feb 24 '16 at 9:11
@thatotherguy I did not know that! I thought that if I use
awk -v x='cd' ...
then it will be used it properly. But when x
is printed awk drops the famous: awk: warning: escape sequence 'c' treated as plain 'c'
error message... Thanks!– TrueY
Feb 24 '16 at 9:11
add a comment |
Use either of these depending how you want backslashes in the shell variables handled (avar
is an awk variable, svar
is a shell variable):
awk -v avar="$svar" '... avar ...' file
awk 'BEGIN{avar=ARGV[1];ARGV[1]=""}... avar ...' "$svar" file
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.
add a comment |
Use either of these depending how you want backslashes in the shell variables handled (avar
is an awk variable, svar
is a shell variable):
awk -v avar="$svar" '... avar ...' file
awk 'BEGIN{avar=ARGV[1];ARGV[1]=""}... avar ...' "$svar" file
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.
add a comment |
Use either of these depending how you want backslashes in the shell variables handled (avar
is an awk variable, svar
is a shell variable):
awk -v avar="$svar" '... avar ...' file
awk 'BEGIN{avar=ARGV[1];ARGV[1]=""}... avar ...' "$svar" file
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.
Use either of these depending how you want backslashes in the shell variables handled (avar
is an awk variable, svar
is a shell variable):
awk -v avar="$svar" '... avar ...' file
awk 'BEGIN{avar=ARGV[1];ARGV[1]=""}... avar ...' "$svar" file
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.
edited Sep 29 '13 at 13:54
answered Sep 29 '13 at 13:22
Ed MortonEd Morton
113k1245103
113k1245103
add a comment |
add a comment |
You could pass in the command-line option -v
with a variable name (v
) and a value (=
) of the environment variable ("${v}"
):
% awk -vv="${v}" 'BEGIN { print v }'
123test
Or to make it clearer (with far fewer v
s):
% environment_variable=123test
% awk -vawk_variable="${environment_variable}" 'BEGIN { print awk_variable }'
123test
add a comment |
You could pass in the command-line option -v
with a variable name (v
) and a value (=
) of the environment variable ("${v}"
):
% awk -vv="${v}" 'BEGIN { print v }'
123test
Or to make it clearer (with far fewer v
s):
% environment_variable=123test
% awk -vawk_variable="${environment_variable}" 'BEGIN { print awk_variable }'
123test
add a comment |
You could pass in the command-line option -v
with a variable name (v
) and a value (=
) of the environment variable ("${v}"
):
% awk -vv="${v}" 'BEGIN { print v }'
123test
Or to make it clearer (with far fewer v
s):
% environment_variable=123test
% awk -vawk_variable="${environment_variable}" 'BEGIN { print awk_variable }'
123test
You could pass in the command-line option -v
with a variable name (v
) and a value (=
) of the environment variable ("${v}"
):
% awk -vv="${v}" 'BEGIN { print v }'
123test
Or to make it clearer (with far fewer v
s):
% environment_variable=123test
% awk -vawk_variable="${environment_variable}" 'BEGIN { print awk_variable }'
123test
edited Sep 29 '13 at 7:57
answered Sep 29 '13 at 7:49
JohnsywebJohnsyweb
99.8k18146212
99.8k18146212
add a comment |
add a comment |
You can utilize ARGV:
v=123test
awk 'BEGIN {print ARGV[1]}' "$v"
Note that if you are going to continue into the body, you will need to adjust
ARGC:
awk 'BEGIN {ARGC--} {print ARGV[2], $0}' file "$v"
add a comment |
You can utilize ARGV:
v=123test
awk 'BEGIN {print ARGV[1]}' "$v"
Note that if you are going to continue into the body, you will need to adjust
ARGC:
awk 'BEGIN {ARGC--} {print ARGV[2], $0}' file "$v"
add a comment |
You can utilize ARGV:
v=123test
awk 'BEGIN {print ARGV[1]}' "$v"
Note that if you are going to continue into the body, you will need to adjust
ARGC:
awk 'BEGIN {ARGC--} {print ARGV[2], $0}' file "$v"
You can utilize ARGV:
v=123test
awk 'BEGIN {print ARGV[1]}' "$v"
Note that if you are going to continue into the body, you will need to adjust
ARGC:
awk 'BEGIN {ARGC--} {print ARGV[2], $0}' file "$v"
answered Jan 15 '17 at 7:05
Steven PennySteven Penny
1
1
add a comment |
add a comment |
I had to insert date at the beginning of the lines of a log file and it's done like below:
DATE=$(date +"%Y-%m-%d")
awk '{ print "'"$DATE"'", $0; }' /path_to_log_file/log_file.log
It can be redirect to another file to save
The double quote - single quote - double quote was exactly what I needed to make mine work.
– user53029
Jul 21 '16 at 14:24
This was already mentioned in the accepted answer as a method you should not use due to code injection vulnerabilities. So the information here is redundant (already described in the accepted answer), and incomplete (does not mention the problems with this method).
– Jason S
Oct 12 '16 at 5:20
add a comment |
I had to insert date at the beginning of the lines of a log file and it's done like below:
DATE=$(date +"%Y-%m-%d")
awk '{ print "'"$DATE"'", $0; }' /path_to_log_file/log_file.log
It can be redirect to another file to save
The double quote - single quote - double quote was exactly what I needed to make mine work.
– user53029
Jul 21 '16 at 14:24
This was already mentioned in the accepted answer as a method you should not use due to code injection vulnerabilities. So the information here is redundant (already described in the accepted answer), and incomplete (does not mention the problems with this method).
– Jason S
Oct 12 '16 at 5:20
add a comment |
I had to insert date at the beginning of the lines of a log file and it's done like below:
DATE=$(date +"%Y-%m-%d")
awk '{ print "'"$DATE"'", $0; }' /path_to_log_file/log_file.log
It can be redirect to another file to save
I had to insert date at the beginning of the lines of a log file and it's done like below:
DATE=$(date +"%Y-%m-%d")
awk '{ print "'"$DATE"'", $0; }' /path_to_log_file/log_file.log
It can be redirect to another file to save
answered Mar 2 '16 at 8:07
SinaSina
32536
32536
The double quote - single quote - double quote was exactly what I needed to make mine work.
– user53029
Jul 21 '16 at 14:24
This was already mentioned in the accepted answer as a method you should not use due to code injection vulnerabilities. So the information here is redundant (already described in the accepted answer), and incomplete (does not mention the problems with this method).
– Jason S
Oct 12 '16 at 5:20
add a comment |
The double quote - single quote - double quote was exactly what I needed to make mine work.
– user53029
Jul 21 '16 at 14:24
This was already mentioned in the accepted answer as a method you should not use due to code injection vulnerabilities. So the information here is redundant (already described in the accepted answer), and incomplete (does not mention the problems with this method).
– Jason S
Oct 12 '16 at 5:20
The double quote - single quote - double quote was exactly what I needed to make mine work.
– user53029
Jul 21 '16 at 14:24
The double quote - single quote - double quote was exactly what I needed to make mine work.
– user53029
Jul 21 '16 at 14:24
This was already mentioned in the accepted answer as a method you should not use due to code injection vulnerabilities. So the information here is redundant (already described in the accepted answer), and incomplete (does not mention the problems with this method).
– Jason S
Oct 12 '16 at 5:20
This was already mentioned in the accepted answer as a method you should not use due to code injection vulnerabilities. So the information here is redundant (already described in the accepted answer), and incomplete (does not mention the problems with this method).
– Jason S
Oct 12 '16 at 5:20
add a comment |
I just changed @Jotne's answer for "for loop".
for i in `seq 11 20`; do host myserver-$i | awk -v i="$i" '{print "myserver-"i" " $4}'; done
add a comment |
I just changed @Jotne's answer for "for loop".
for i in `seq 11 20`; do host myserver-$i | awk -v i="$i" '{print "myserver-"i" " $4}'; done
add a comment |
I just changed @Jotne's answer for "for loop".
for i in `seq 11 20`; do host myserver-$i | awk -v i="$i" '{print "myserver-"i" " $4}'; done
I just changed @Jotne's answer for "for loop".
for i in `seq 11 20`; do host myserver-$i | awk -v i="$i" '{print "myserver-"i" " $4}'; done
answered Apr 10 '18 at 7:34
edibedib
4031614
4031614
add a comment |
add a comment |
for i in chr{1..22} chrX chrY
do
awk -v chr="$i" '$1==chr' ../snp150.hg19.txt >> $chr.vcf.bed
echo $i
done
add a comment |
for i in chr{1..22} chrX chrY
do
awk -v chr="$i" '$1==chr' ../snp150.hg19.txt >> $chr.vcf.bed
echo $i
done
add a comment |
for i in chr{1..22} chrX chrY
do
awk -v chr="$i" '$1==chr' ../snp150.hg19.txt >> $chr.vcf.bed
echo $i
done
for i in chr{1..22} chrX chrY
do
awk -v chr="$i" '$1==chr' ../snp150.hg19.txt >> $chr.vcf.bed
echo $i
done
answered Jul 20 '18 at 15:13
Shicheng GuoShicheng Guo
643715
643715
add a comment |
add a comment |
protected by Inian Apr 27 '18 at 19:37
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?
1
I like the -v as shown below, but this is really a great exercise in thinking about how to protect things from the shell. Working through this, my first cut use backslashes on spaces and dollar signs. Needless to say the examples here were well worth my time.
– Chris
Dec 20 '16 at 21:00
Related: Difference between single and double quotes in awk.
– codeforester
May 11 '18 at 18:45