2

I have an awk script in a bash script that I am starting to generalise.

I would like to put the string "$3" into a bash variable and use that variable in the awk script. This would allow me to easily update the script as needed.

For example:

NR > 1 && $3 != p { 
   #blah blah blah 
   printf("%s_%s%s", $3, header[i], OFS) 
}

would become something like

foo="$3"
NR > 1 && $foo != p { 
   #blah blah blah 
   printf("%s_%s%s", $foo, header[i], OFS) 
}

I've tried various combinations of foo="$3", ='$3', "$foo", '$foo', and ${foo} and can't get it to work.

What am I doing wrong?

.

I want to replace each instance of "$3" with "$foo" so that I only need to update $foo if I want to change the script.

The complete awk script inside the bash script:

#!/bin/bash

#these are bash variables
file=$1
header=$(head -n1 $file)


############################
# awk script               #
############################
read -d '' awkscript << 'EOF'
BEGIN { OFS = "\\t" }

/^@/  {
   for (i = 1; i <= NF; ++i)
      header[i] = $i
   next
}

NR > 1 && $3 != p {
   #output two blank lines if needed
   if (print_blank) {
      print "\\n"
   }
   print_blank = 1 

   for (i = 1; i <= 3; ++i)
      printf("%s%s", header[i], OFS)

   for (i = 4; i < NF; ++i)
      printf("%s_%s%s", $3, header[i], OFS)
   printf("%s_%s%s", $3, header[NF], ORS)
}

{ p=$3; print }
EOF

############################
# end awk script           #
############################

#blah
#blah
#blah

awk "$awkscript" ${tmp} > ${output}
5
  • Is $3 coming from a positional parameter in your bash script?
    – jesse_b
    Jan 10, 2019 at 1:17
  • @Jesse_b No. I want to put "$3" into the awk script so that it will match the third token in the string fed to the awk script.
    – masher
    Jan 10, 2019 at 1:19
  • Yes but where is $3 coming from?
    – jesse_b
    Jan 10, 2019 at 1:20
  • Are you trying to select a field based on the input variable?
    – jesse_b
    Jan 10, 2019 at 1:21
  • @Jesse_b I'm telling awk to match the third token. This happens in a bunch of places. I want to pull that out and replace it with a single variable so I can change that single variable to match the 4th or 5th or whateverth token, without having to find every single instance of it each time.
    – masher
    Jan 10, 2019 at 1:25

1 Answer 1

3

You can inject a shell variable to your awk script with the -v option:

#!/bin/bash

#these are bash variables
file=$1
header=$(head -n1 $file)
awktoken=$2

############################
# awk script               #
############################
read -d '' awkscript << 'EOF'
BEGIN { OFS = "\\t" }

/^@/  {
   for (i = 1; i <= NF; ++i)
      header[i] = $i
   next
}

NR > 1 && $variable != p {
   #output two blank lines if needed
   if (print_blank) {
      print "\\n"
   }
   print_blank = 1 

   for (i = 1; i <= 3; ++i)
      printf("%s%s", header[i], OFS)

   for (i = 4; i < NF; ++i)
      printf("%s_%s%s", $variable, header[i], OFS)
   printf("%s_%s%s", $variable, header[NF], ORS)
}

{ p=$variable; print }
EOF

############################
# end awk script           #
############################

awk -vvariable="$awktoken" "$awkscript" ${tmp} > ${output}

variable is the name of the variable in this example. Normally you would call it without the $ but that is left in for it to expand to $3 or whatever number you choose

1
  • Yay! In my case, awktoken=3
    – masher
    Jan 10, 2019 at 2:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .