Is there a way to define a user-defined function inside an awk statement which is inside a bash script?

I think the question speaks for itself. I am a beginner so please let me know if this is possible or not. If not, came you give me a better solution because my bash script depends heavily on certain awk statements but the majority of the script is in bash. I am comparing two files using an awk statement in my bash script. Basically checking if the values are the same or not. (see the files below)

file1.txt

Name  Col1  Col2  Col3 
-----------------------
row1  1     4     7         
row2  2     5     8          
row3  3     6     9

file2.txt

Name  Col1  Col2  Col3   
-----------------------         
row1  1     4     7 
row2  2     5     999

Here is the structure of my bash script:

#!/bin/bash
.
.
.

awk -F '\t' '
              # skips first two lines
              FNR < 2 {next}                       
              FNR == NR {           
                for (i = 2; i <= NF; i++) {
                  a[i,$1] = $i;      
                }    
                b[$1];           
                next;       
              }

              ($1 in b) {                          

                for (i = 2; i <= NF; i++) 
                {
                   # does something
                }
              }
' file1.txt file2.txt
.
.
.

I have a lot of repetitive code that are only useful in the awk statements and so I want to create a function that would be placed in the awk statement to avoid repetition. Is this possible?

Let me know if further explanation is required.


Solution 1:

Sure, just define functions:

awk '
function foo() {
   print "Hello World"
}
BEGIN {
    foo()
    foo()
}
'

Solution 2:

If you are asking how to reuse a piece of Awk code in multiple scripts without saving it in a separate file, you can define a shell string and interpolate it.

awkfn='function foo () { print "Hiya universe" }'

awk -F : "$awkfn"'BEGIN { foo() }'

Notice how you need double quotes for the variable to be interpolated, but generally want single quotes around your Awk code. I put a double-quoted string immediately next to a single-quoted string (no whitespace between them) but there are other ways to accomplish the same thing.