如何在awk中定义新命令或宏

时间:2014-12-17 16:46:06

标签: shell macros awk command mawk

我喜欢定义一个包装现有awk命令的新命令,例如print。但是,我不想使用函数:

#wrap command with function
function warn(text) { print text > "/dev/stderr" }
NR%1e6 == 0 {
  warn("processed rows: "NR)
}

相反,我喜欢定义一个可以在没有括号的情况下调用的新命令:

#wrap command with new command ???
define warn rest... { print rest... > "/dev/stderr" }
NR%1e6 == 0 {
  warn "processed rows: "NR
}

我能想象的一个解决方案是使用预处理器并且可能很好地设置awk脚本的shebang以调用此preproccessor,然后是awk。但是,我更希望有一个纯粹的awk解决方案。

注意:解决方案也应该在我使用的mawk中工作,因为它比 vanilla GNU / awk快得多。

更新:讨论显示gawk(GNU / awk)非常快,并且不需要mawk

2 个答案:

答案 0 :(得分:0)

查看Mawk的源代码我发现命令很特殊,无法在运行时添加。来自kw.c

keywords[] =
{
    { "print",    PRINT },
    { "printf",   PRINTF },
    { "do",       DO },
    { "while",    WHILE },
    { "for",      FOR },
    { "break",    BREAK },
    { "continue", CONTINUE },
    { "if",       IF },
    { "else",     ELSE },
    { "in",       IN },
    { "delete",   DELETE },
    { "split",    SPLIT },
    { "match",    MATCH_FUNC },
    { "BEGIN",    BEGIN },
    { "END",      END },
    { "exit",     EXIT },
    { "next",     NEXT },
    { "nextfile", NEXTFILE },
    { "return",   RETURN },
    { "getline",  GETLINE },
    { "sub",      SUB },
    { "gsub",     GSUB },
    { "function", FUNCTION },
    { (char *) 0, 0 }
};

您可以通过修补Mawk的C代码来添加新命令。

答案 1 :(得分:0)

你不能在任何awk中执行此操作,如果不编写awk语言解析器,就不能在awk之外执行此操作,那么你也可以编写自己的awk-like命令,然后实际上不再是awk尽管它的行为与该名称的任何其他命令的行为不同。

奇怪的是你将GNU awk称为" vanilla"当它具有比任何其他当前可用的awk更多有用的功能,而mawk只是一个针对速度优化的精简版awk,仅在非常罕见的情况下才需要。