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") }'
  • 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 ? – Sergiy Kolodyazhnyy Jul 28 '17 at 5:29
  • wrap.awk just pushes a string onto the next line if it is over a certain length. – ZeroPhase Jul 28 '17 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 '17 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 '17 at 16:17
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.

  • 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 '17 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.