Parsing awk中的性能比较?

Parsing awk中的性能比较?,parsing,awk,logparser,Parsing,Awk,Logparser,我有一个python脚本,它在一些日志中运行,我认为在部署它之前,对其他一些方法进行一些基准测试会很有帮助。在查看awk时,我希望将开销降至最低,以便在击败稍微优化的python变体时获得“公平”的震撼 我的日志条目如下所示: -------- SomeField=SomeValue OptionallyAppearingField=WhoKnowsWhat AnotherField=AnotherValue ExtraStuff=OneBonusKey=1,SecondBonusKey=2,T

我有一个python脚本,它在一些日志中运行,我认为在部署它之前,对其他一些方法进行一些基准测试会很有帮助。在查看
awk
时,我希望将开销降至最低,以便在击败稍微优化的python变体时获得“公平”的震撼

我的日志条目如下所示:

--------
SomeField=SomeValue
OptionallyAppearingField=WhoKnowsWhat
AnotherField=AnotherValue
ExtraStuff=OneBonusKey=1,SecondBonusKey=2,ThirdBonusKey=3,...
--------
当我们的
ThirdBonusKey
s中有一个存在并且有一定的值(实际上只是数字1)时,我很想得到另一个字段的值

这里的“愚蠢”方法是将我们的
RS
设置为
'-'
,然后只对
$0
应用正则表达式两次,首先查看
ThirdBonusKey=1
是否在记录中,然后提取
另一个字段=(所需的值)

但这似乎是一个不公平的比较,因为它只是在这个问题上抛出了一个正则表达式(两次!)。如果没有保证字段的顺序来利用awk的酷FS技能,这里有没有更快或更合适的方法?答案可能只是“这不是awk的工作”,我想这也没关系

Cyrus善意地指出,我上面给出的代码草图在技术上不是代码,他在技术上是正确的,所以这里有一个相当愚蠢的实现:

awk 'BEGIN{RS="--------"} { if ($0 ~ /ThirdBonusKey=1/) { for(i=1;i<NF;i++) {if ($i ~ "AnotherField=") { print $i }}}}'
我们期望产量

AnotherField=DesiredValue1

最有效的方法是:

$ awk '/^AnotherField=/{val=$0; next} /[=,]ThirdBonusKey=1(,|$)/{print val}' file
AnotherField=DesiredValue1
但更强大、更容易增强,以后可以做任何你想做的事情:

$ cat tst.awk
BEGIN { FS="[,=[:space:]]"; OFS="=" }
/^-+$/ {
    if ( f["ExtraStuff_ThirdBonusKey"] == 1 ) {
        print "AnotherField", f["AnotherField"]
    }
    delete f
    next
}
{
    if ( $1 == "ExtraStuff" ) {
        pfx = $1
        sub(/[^=]+=/,"")
        f[pfx] = $0
        pfx = pfx "_"
    }
    else {
        pfx = ""
    }
    for (i=1; i<NF; i+=2) {
        f[pfx $i] = $(i+1)
    }
}

$ awk -f tst.awk file
AnotherField=DesiredValue1


假设您可以创建任何条件和/或以任何输入或输出顺序打印所需的任何字段组合。

我希望效率最高的是:

$ awk '/^AnotherField=/{val=$0; next} /[=,]ThirdBonusKey=1(,|$)/{print val}' file
AnotherField=DesiredValue1
但更强大、更容易增强,以后可以做任何你想做的事情:

$ cat tst.awk
BEGIN { FS="[,=[:space:]]"; OFS="=" }
/^-+$/ {
    if ( f["ExtraStuff_ThirdBonusKey"] == 1 ) {
        print "AnotherField", f["AnotherField"]
    }
    delete f
    next
}
{
    if ( $1 == "ExtraStuff" ) {
        pfx = $1
        sub(/[^=]+=/,"")
        f[pfx] = $0
        pfx = pfx "_"
    }
    else {
        pfx = ""
    }
    for (i=1; i<NF; i+=2) {
        f[pfx $i] = $(i+1)
    }
}

$ awk -f tst.awk file
AnotherField=DesiredValue1


假设您可以创建任何条件和/或以任何输入或输出顺序打印任何字段组合。

欢迎使用堆栈溢出。这也是一个面向专业和热情程序员的问答页面。在问题中添加您自己的代码。你至少要展示你自己为解决这个问题所做的大量研究。你所描述的似乎是一个合理的方法。嗯?每次看到另一个字段时,请拾取它们。当你遇到
--
打印
另一个字段时
如果你看到了正确的
BonusKey
,忘记一切,然后继续。@MarkSetchell听起来像是在提示你的问题表明
额外的内容
可能在
另一个字段
之前,但你的例子暗示它不在前面。请问是哪一个?欢迎来到Stack Overflow。这也是一个面向专业和热情程序员的问答页面。在问题中添加您自己的代码。你至少要展示你自己为解决这个问题所做的大量研究。你所描述的似乎是一个合理的方法。嗯?每次看到另一个字段时,请拾取它们。当你遇到
--
打印
另一个字段时
如果你看到了正确的
BonusKey
,忘记一切,然后继续。@MarkSetchell听起来像是在提示你的问题表明
额外的内容
可能在
另一个字段
之前,但你的例子暗示它不在前面。请问是哪一个?
$ awk -f tst.awk file
----
> f[OptionallyAppearingField]=WhoKnowsWhat
> f[AnotherField]=DesiredValue1
> f[ExtraStuff_SecondBonusKey]=2
> f[ExtraStuff_ThirdBonusKey]=1
> f[ExtraStuff_OneBonusKey]=1
> f[SomeField]=SomeValue
> f[ExtraStuff]=OneBonusKey=1,SecondBonusKey=2,ThirdBonusKey=1,...
AnotherField=DesiredValue1
----
> f[OptionallyAppearingField]=WhoKnowsWhat
> f[AnotherField]=DesiredValue2
> f[ExtraStuff_SecondBonusKey]=2
> f[ExtraStuff_ThirdBonusKey]=0
> f[ExtraStuff_OneBonusKey]=1
> f[SomeField]=SomeValue
> f[ExtraStuff]=OneBonusKey=1,SecondBonusKey=2,ThirdBonusKey=0,...
----
> f[SomeField]=
> f[ExtraStuff]=
----