1

I have an awk file that loads other awk files. Rather than calling the loading code everytime I run the main function of the file I'm trying to load everything in a BEGIN statement first, but if I do that the function itself never gets run. Is there anyway to have a BEGIN statement, and functions called from outside of the script?

My awk script:

#! /usr/bin/awk -f

function include(includeFile) {INCLUDE_FILES[includeFile]}
function sourceIncludes()
{
    if(!l)
    {
        getline t < "/proc/self/cmdline"; split(t,T, "\0")
        scriptname=T[3]
        for (i = 1; i < ARGC; i++) 
            args=args " "ARGV[i]
        for(iFile in INCLUDE_FILES )
            inc = inc " -f "iFile
        cmd=sprintf("%s %s -v l=1 -- %s\n",scriptname,inc,args)
        system(cmd); exit
    }
}

function pkginfo(pkg)
{
    { print pkg }
}

BEGIN {
    include("wrap.awk")
    sourceIncludes()
}

wrap.awk contents:

#! /usr/bin/awk -f

function wrap(text, q, y, z)
{
    while(text)
    {
        q = match(text, / |$/)
        y += q
        if(y >= 80)
        {
            z = z RS sprintf("%c", 0x2502) #chr(2502)#"\\u2502"
            for(i = 0; i < 20; i++)
                z = z FS
            y = q - 1
        }
        else if(z)
            z = z FS
        z = z substr(text, 1, q - 1)
        text = substr(text, q + 1)
    }
    return z
}

This is how I call everything from bash / zsh:

awk -f ~/.ZSH_CUSTOM/awkscripts/pkginfo.awk -e '{ pkginfo("test") }'
4
  • 1
    Tried your script, seems to work for me. I've GNU awk on Ubuntu 16.04. What you got there ? What's the contents of wrap.awk ? Jul 28, 2017 at 5:29
  • wrap.awk just pushes a string onto the next line if it is over a certain length.
    – ZeroPhase
    Jul 28, 2017 at 6:07
  • When I ran this on a Mac (appropriately modified), what was happening was, that the BEGIN commands started to run until it got to the exit; and then it processed exit before getting to the commands passed in with the -e switch. Let me know if that's not what's going on for you.
    – Alex
    Aug 22, 2017 at 21:03
  • Yeah, that's what's happening to me too. Without the exit it just pauses at the system call. I found that part on a post about how to include multiple awk scripts in one script. None of the solutions seem to work correctly. tek-tips.com/viewthread.cfm?qid=1100705
    – ZeroPhase
    Aug 23, 2017 at 16:17

1 Answer 1

0

You're calling exit from BEGIN{}, this means anything not in an earlier BEGIN{} or END{} won't be executed.

Even without the exit, your code

{ pkginfo("test") }

will not execute until a line of input (stdin) in available, this is the way awk works. You could work around that by calling a function with your code (main() for example) with your code, and then exit at the end of the last BEGIN block.

awk is quite general purpose, but it really wants to read lines of input, and match them to patterns. This is why your code appears to hang,.

Or, you may use

BEGIN { pkginfo("test") }

though you may need to understand the ordering of all the BEGIN blocks. Or, if you call exit at the end of the final BEGIN you can put your code in an END{} block. No input will be expected if you only have BEGIN/END blocks.

Since you are running on a Linux system you quite likely are using gawk rather than a plain awk (nawk, mawk or similar), almost certainly I think since -e is also a gawk version 4 extension ;-) In this case you can use @include which eliminates some code. Otherwise for any other awk thes wrapper script igawk seems a cleaner way to accomplish include capability.

1
  • Alright, so when people try to get you to write portable code their wanting your code to work on the more esoteric BSD or sun systems right? I just need to worry about Linux, and maybe Mac support at the most.
    – ZeroPhase
    Oct 7, 2017 at 21:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.