Awk: function call outside awk

Update:

I am working on a modular shell script that calls usage() at a different subprocess level. script sample.sh has a structure that looks like below:

 sample.sh ├─ ... ├─ usage() ├─ awk ├─ usage() ├─ ... 

usage() displays a summary of how to use the script (e.g. available arguments and descriptions). When run for the first time, usage() displayed at the beginning of the script. Examples of other conditions for calling usage() :

  • awk cannot verify input from stdio or files

  • argument --help received

  • other user crashes occurred

I would like to call the identical usage() function, from the shell and its direct child process, awk .


The original question:

The usage() sample.sh prints the print instruction as desired.

 $cat sample.sh #!/bin/sh awk ' BEGIN { usage() } function usage() { print "function inside of awk" } ' $./sample.sh function inside of awk 

To take usage() out of awk and put it as a local function in sample.sh~ , I tried:

 $cat sample.sh~ #!/bin/sh usage() { print "function outside of awk" } awk ' BEGIN { usage() } ' $./sample.sh~ awk: calling undefined function usage source line number 3 

As we can see, we get the error message "undefined function use" in sample.sh~ . How to improve it?

+6
source share
3 answers

I find a way to call a function from awk

enter the code below into the file, for example, name it a.sh

 $ cat a.sh usage() { print "function outside of awk" } $ chmod +x a.sh 

then you can call the function in awk

 #!/bin/sh awk ' BEGIN { system(". a.sh;usage") }' 
+4
source

A child process cannot call a function in the parent and vice versa. Even in the same language.

What you can do is run another instance of the shell script containing your awk script. For example, save this in a script called ./script.sh :

 #!/bin/sh -e usage() { echo usage: ... exit 1 } test "$1" = --usage && usage awk -v usage_script="$0" ' function usage() { system(usage_script " --usage") } BEGIN { usage() }' 

Make it executable and run it as ./script.sh . In this script, the usage function inside the internal awk script simply restarts the containing shell script using the --usage script. Keep in mind that there will be 3 processes: shell -> awk -> shell. This cannot be done in one process.

Original answer

If you move the definition of the usage function outside of awk , then this is normal that you cannot execute from within. If you want to execute awk commands, you must be inside the awk interpreter and can only use what is defined inside.

Note that this is what you are looking for, but you can move the function definition to another awk file and process it with awk , for example:

 cat <<EOF > functions.awk function usage() { print "function in functions.awk" } EOF awk -f functions.awk -e ' BEGIN { usage() } ' 
+2
source

With bash another option is to export shell functions using export -f , which are then made available to awk by calling system() :

 #!/usr/bin/env bash usage() { echo "function outside of awk" } # Export the usage() function. export -f usage awk ' BEGIN { system("/usr/bin/env bash -c usage") }' 

Please note that awk calls sh with system() , which may or may not be bash - if it is IS bash (for example, on OSX), you do not need strictly /usr/bin/env bash -c but leaving it should force its work on most platforms (which have bash).

+2
source

All Articles