Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

awk: calling a function outside of awk

Tags:

bash

shell

awk

Update:

I'm working on a modular shell script which calls usage() in different level of subprocess. The script sample.sh has the structure resembles below:

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

usage() displays brief information on how to use the script (e.g. available arguments and its descriptions). When executed for the first time, usage() is displayed in the beginning of the script. Examples of other conditions for usage() invocation include:

  1. awk fails to validate input from stdio or files

  2. argument--help is received

  3. other user-derived failures are occurred

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


Original Question:

Function, usage() of sample.sh prints its print statement 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 out usage() from 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 observe, we get the error message saying "undefined function usage" in sample.sh~. How should I improve it?

like image 467
melvynkim Avatar asked Feb 15 '14 06:02

melvynkim


People also ask

How do you call a function in awk?

You have to write an equivalent awk function, e.g. add this to your awk script: function dots(n) {while(n-- > 0) print "."}

How awk communicate to an external process?

Call External Command From awkawk + cp: Read input of a file list, and copy the files to a required destination with a defined name pattern. awk + md5sum: Read input containing a list of filenames, output the filename and the MD5 hash of the file.

Can we use awk inside awk?

The condition will not be effective inside awk since data is piped to sendmail regardless.

How do I print a specific line in awk?

To print a blank line, use print "" , where "" is the empty string. To print a fixed piece of text, use a string constant, such as "Don't Panic" , as one item. If you forget to use the double-quote characters, your text is taken as an awk expression, and you will probably get an error.


2 Answers

I find a way to call function out of awk

put below code in a file, such as call 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")
    }'
like image 183
2 revs Avatar answered Oct 10 '22 18:10

2 revs


With bash, another option is to export shell functions with export -f, which then become available to awk via the system() call:

#!/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") 
  }'

Note that awk invokes sh with system(), which may or may not be bash - if it IS bash (e.g., on OSX), you don't strictly need the /usr/bin/env bash -c portion, but leaving it in should make it work on most platforms (that have bash).

like image 36
mklement0 Avatar answered Oct 10 '22 18:10

mklement0