如果 awk 文件中有 begin 语句,则 awk 函数不会被调用

如果 awk 文件中有 begin 语句,则 awk 函数不会被调用

我有一个awk加载其他awk文件的文件。我不是每次运行文件的主函数时都调用加载代码,而是尝试BEGIN首先加载语句中的所有内容,但如果我这样做,函数本身就永远不会运行。是否有一个BEGIN语句,以及从脚本外部调用的函数?

我的awk脚本:

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

包装.awk 内容:

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

这就是我从 bash / zsh 调用所有内容的方式:

awk -f ~/.ZSH_CUSTOM/awkscripts/pkginfo.awk -e '{ pkginfo("test") }'

答案1

exit您从调用BEGIN{},这意味着任何不在较早版本中的内容BEGIN{}END{}不会被执行。

即使没有出口,你的代码

{ pkginfo("test") }

直到有一行输入(stdin)可用时才会执行,这就是 awk 的工作方式。您可以通过使用您的代码(main()例如)调用函数来解决这个问题,然后exit在最后一个块的末尾BEGIN

awk是相当通用的目的,但它真的想要读取输入行,并将它们与模式匹配。这就是您的代码似乎挂起的原因。

或者,您可以使用

BEGIN { pkginfo("test") }

尽管您可能需要了解所有块的顺序BEGIN。或者,如果您exit在决赛结束时调用BEGIN,您可以将代码放在一个END{}块中。如果您只有BEGIN/块,则不会有任何输入END

由于您在 Linux 系统上运行,您很可能正在使用gawk而不是普通的awknawkmawk类似的),几乎可以肯定我认为since-e也是gawk版本4扩展;-)在这种情况下您可以使用@include这消除了一些代码。否则对于任何其他 awk 包装脚本igawk似乎是实现包含功能的更干净的方法。

相关内容