How to pass bash variables to awk script - awk

# My vars
index=test
type=book
I'm trying to pass these variables to awk
awk -v index="$index" -v type="$type" 'BEGIN{print "{\"create\": {\"_index\":\"index\", \"_type\":\"type\"}}"}; {print}; END {printf "\n"}'
Desired output
{"create": {"_index":"test", "_type":"book"}}

Don't embed the variables in the string:
awk -v idx="$index" -v type="$type" 'BEGIN{print "{\"create\": {\"_index\":\"" idx "\", \"_type\":\"" type "\"}}"} {print} END {print ""}'
You can't use index as an awk variable name, btw, as that's the name of an awk function.

Related

How to use awk to find the line starting with a variable

I know 2 things about awk:
1.
PAT='aGeneName'
awk -v var="$PAT" '$3 ~ var {print $0}' file.txt # will print the line where 3rd field includes the variable $PAT
2.
awk '$3 ~ /^aGeneName/' file.txt # will print the line where 3rd field starts with string "aGeneName"
But what I want is the combination of these two: I want to print the line where the 3rd field starts with the variable $PAT, something like
PAT='aGeneName'
awk -v var="$PAT" '$3 ~ /^var/ {print $0}' file.txt # but this is wrong, since variable can't be put into //
One way is like this:
PAT='aGeneName'
awk -v var="$PAT" '$3 ~ "^" var {print $0}' file.txt
And the {print $0} can be saved here, it's implied.
Another way, when the pattern var is a simple string, no RegEX character inside:
PAT='aGeneName'
awk -v var="$PAT" 'index($3, var)==1' file.txt

Awk print string with variables

How do I print a string with variables?
Trying this
awk -F ',' '{printf /p/${3}_abc/xyz/${5}_abc_def/}' file
Need this at output
/p/APPLE_abc/xyz/MANGO_abc_def/
where ${3} = APPLE
and ${5} = MANGO
printf allows interpolation of variables. With this as the test file:
$ cat file
a,b,APPLE,d,MANGO,f
We can use printf to achieve the output you want as follows:
$ awk -F, '{printf "/p/%s_abc/xyz/%s_abc_def/\n",$3,$5;}' file
/p/APPLE_abc/xyz/MANGO_abc_def/
In printf, the string %s means insert-a-variable-here-as-a-string. We have two occurrences of %s, one for $3 and one for $5.
Not as readable, but the printf isn't necessary here. Awk can insert the variables directly into the strings if you quote the string portion.
$ cat file.txt
1,2,APPLE,4,MANGO,6,7,8
$ awk -F, '{print "/p/" $3 "_abc/xyz/" $5 "_abc_def/"}' file.txt
/p/APPLE_abc/xyz/MANGO_abc_def/

pass and compare external variable in awk command

how to pass and compare an external variable in awk command? is it also dependent on unix shell that we are using
I am trying to do :
mgrid=`echo $file1 | awk -F'|' '{ print $40}' `
echo $mgrid
var=`/usr/bin/more $HOME/pwd_date_chk/file2.txt | awk -F'|' ' -v search="$mgrid" '{ $41 ~ search print $15}'`
echo $var
awk can read the input from file. No need to use more. You can try this,
mgrid=`echo $file1 | awk -F'|' '{ print $40}' `
echo $mgrid
var=`awk -F'|' -v search="$mgrid" '$41 ~ search {print $15}' $HOME/pwd_date_chk/file2.txt`
echo $var

Why does an awk field assignment lose the output field separator?

This command works. It outputs the field separator (in this case, a comma):
$ echo "hi,ho"|awk -F, '/hi/{print $0}'
hi,ho
This command has strange output (it is missing the comma):
$ echo "hi,ho"|awk -F, '/hi/{$2="low";print $0}'
hi low
Setting the OFS (output field separator) variable to a comma fixes this case, but it really does not explain this behaviour.
Can I tell awk to keep the OFS?
When you modify the line ($0) awk re-constructs all columns and puts the value of OFS between them which by default is space. You modified the value of $2 which means you forced awk to re-evaluate$0.
When you print the line as is using $0 in your first case, since you did not modify any fields, awk did not re-evaluated each field and hence the field separator is preserved.
In order to preserve the field separator, you can specify that using:
BEGIN block:
$ echo "hi,ho" | awk 'BEGIN{FS=OFS=","}/hi/{$2="low";print $0}'
hi,low
Using -v option:
$ echo "hi,ho" | awk -F, -v OFS="," '/hi/{$2="low";print $0}'
hi,low
Defining at the end of awk:
$ echo "hi,ho" | awk -F, '/hi/{$2="low";print $0}' OFS=","
hi,low
You first example does not change anything, so all is printed out as the input.
In second example, it change the line and it will use the default OFS, that is (one space)
So to overcome this:
echo "hi,ho"|awk -F, '/hi/{$2="low";print $0}' OFS=","
hi,low
In your BEGIN action, set OFS = FS.

awk command with search string variable

Configuration.xml has "mysearchstring" at position (line) 23.
If I use the following statement, it returns me line 23
awk '/"mysearchstring"/{print NR}' Configuration.xml
But if I use an assigned variable, it returns me nothing
str="mySearchString";awk '/$str/{print NR}' Configuration.xml
Can someone tell me what is incorrect in the second statement?
You need to pass the variable to awk with -v and then use the ~ comparison:
awk -v myvar="$str" '$0 ~ myvar {print NR}' Configuration.xml
Example
$ cat a
hello
how
are
you
$ awk '/e/ {print NR}' a <---- hardcoded
1
3
$ awk -v myvar="e" '$0~myvar {print NR}' a <---- through variable
1
3
You can use the command-line option -v to pass variables to awk:
awk -v searchstr="$str" '$0 ~ searchstr { print NR }'
Or you can pass variable like this, after code:
awk '$0~s {print NR}' s="$str" file