5

I want to pass 2 shell (bash) variables from into an awk statement. In this example the variables are marker1 and marker2

ubuntu@ubuntutest:/tmp$ echo $marker1
###___showhost___###
ubuntu@ubuntutest:/tmp$ echo $marker2
###___showhostset___###
ubuntu@ubuntutest:/tmp$

The script will extract all the lines of text between to different strings/markers ($marker1 and $marker2) from text file - file.in

ubuntu@ubuntutest:/tmp$ cat file.in 
###___showhost___###
 Id Name        Persona -WWN/iSCSI_Name- Port 
115 server5295 VMware  5005638024D3E8E6 1:2:4
116 server5296 VMware  5005638024D3EA86 1:2:4
117 server5297 VMware  5005638024D3F5D2 1:2:4
142 server5302 VMware  5005638024D3E8B6 1:2:4
143 server5303 VMware  5005638024D3E9C6 1:2:4
144 server5304 VMware  5005638024D3F4F2 1:2:4
###___showhostset___###
Id Name              Members    
 0 Mgt_Stack         server5295
 1 Cluster1          server5302
                     server5304
ubuntu@ubuntutest:/tmp$

If I run the awk statement, where I use the actual string values for variables marker1/marker2 ###___showhost___### and ###___showhostset___### respectively instead of using the variables themselves (within awk) I get a positive result. However, I want to put the awk statement in a bash scripts and need to read the variables marker1/marker2.

ubuntu@ubuntutest:/tmp$ awk '/^###___showhost___###/{flag=1;next}/^###___showhostset___###/{flag=0}flag' file.in 
 Id Name        Persona -WWN/iSCSI_Name- Port 
115 server5295 VMware  5005638024D3E8E6 1:2:4
116 server5296 VMware  5005638024D3EA86 1:2:4
117 server5297 VMware  5005638024D3F5D2 1:2:4
142 server5302 VMware  5005638024D3E8B6 1:2:4
143 server5303 VMware  5005638024D3E9C6 1:2:4
144 server5304 VMware  5005638024D3F4F2 1:2:4
ubuntu@ubuntutest:/tmp$

However, when i use the 2 variables $marker1 and $marker2 in the awk statement I get no output.

ubuntu@ubuntutest:/tmp$ awk '/^"'$marker1'"/{flag=1;next}/^"'$marker2'"/{flag=0}flag' file.in 
ubuntu@ubuntutest:/tmp$

Any help greatly appreciated !!!

ccpizza
  • 28,968
  • 18
  • 162
  • 169
vtecdec
  • 51
  • 1
  • 1
  • 2

2 Answers2

7

You have to use -v, Getting shell variables into awk may be done in several ways. Some are better than others.

This is the best way to do it (Please note use a space after -v or it will be less portable. E.g., awk -v var= not awk -vvar)

# your shell variables
marker1="###___showhost___###"
marker2="###___showhostset___###"

# and passing them to awk
awk -v market1="$market1" -v market2="$market2" '
       $0 ~ "^"market1{found=1;next}
       $0 ~ "^"market2{found=0}found' file.in

Example:

akshay@db-3325:~$ foo="this is my shell variable"
akshay@db-3325:~$ awk -v myvar="$foo" 'BEGIN{print myvar}'
this is my shell variable
Akshay Hegde
  • 16,536
  • 2
  • 22
  • 36
  • Thanks Akshay, thats working now for me. The awk statement differs slightly from the original one, can you explain how it works (to extract the text between variables market1 & market2) now. thanks – vtecdec Mar 16 '17 at 18:19
  • @vtecdec: I just changed `flag` to `found` for better readability rest all same, `$0` means current record/line/row , `$0 ~"^"marker1{}` means if record starts with value of marker1 then make variable `found=1` and go to next line, same way for market2 which makes `found=0`, and `}found` whenever `found` is non zero, then prints current record/row/line – Akshay Hegde Mar 16 '17 at 18:39
0

Here's the usage, according to awk man page (for awk -version "20200816"):

awk [ -F fs ] [ -v var=value ] [ 'prog' | -f progfile ] [ file ...  ]

Also from the man page, there are two ways of doing assignment. One like this:

Any file of the form var=value is treated as an assignment, not a filename, and is executed at the time it would have been opened if it were a filename.

And the other like this:

The option -v followed by var=value is an assignment to be done before prog is executed; any number of -v options may be present.

The question posted here is addressed by the second assignment option, using -v, which is described well in the answer posted by Akshay. Here's another simple example using -v assignment:

% X=aardvark                    
% echo | awk -v x=$X '{print x}'
aardvark
Kaan
  • 5,434
  • 3
  • 19
  • 41