Производительные сравнения в awk? - PullRequest
0 голосов
/ 27 февраля 2020

У меня есть сценарий python, который проходит через некоторые журналы и решил, что было бы полезно сделать несколько тестов по сравнению с некоторыми другими подходами перед его развертыванием. Глядя на awk, я надеюсь минимизировать накладные расходы, чтобы получить «справедливый» толчок при победе над несколько оптимизированным вариантом python.

Мои записи журнала выглядят так:

--------
SomeField=SomeValue
OptionallyAppearingField=WhoKnowsWhat
AnotherField=AnotherValue
ExtraStuff=OneBonusKey=1,SecondBonusKey=2,ThirdBonusKey=3,...
--------

И я стремлюсь получить значение AnotherField, когда один из наших ThirdBonusKey s существует и имеет определенное значение (фактически только номер 1).

«Глупый» способ - установить RS на '--------', а затем дважды применить регулярное выражение к $0, сначала посмотреть, есть ли в записи ThirdBonusKey=1, а затем выписка AnotherField=(desired_value).

Но это кажется несправедливым сравнением, учитывая, что он просто бросает регулярное выражение в задачу (дважды!). Без гарантированного упорядочения полей, чтобы использовать классные навыки FS awk, есть ли более быстрый или более подходящий подход? Возможно, ответ просто «это не работа для awk», и это тоже нормально, я думаю.

Сайрус любезно указал, что набросок кода, который я привел выше, технически не является кодом, и он технически корректен, поэтому вот довольно глупая реализация:

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

Учитывая ввод

--------
SomeField=SomeValue
OptionallyAppearingField=WhoKnowsWhat
AnotherField=DesiredValue1
ExtraStuff=OneBonusKey=1,SecondBonusKey=2,ThirdBonusKey=1,...
--------
SomeField=SomeValue
OptionallyAppearingField=WhoKnowsWhat
AnotherField=DesiredValue2
ExtraStuff=OneBonusKey=1,SecondBonusKey=2,ThirdBonusKey=0,...
--------
SomeField=
ExtraStuff=
--------

мы ожидаем выхода

AnotherField=DesiredValue1

1 Ответ

2 голосов
/ 28 февраля 2020

Наиболее эффективно, я ожидаю:

$ 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

Этот второй скрипт сначала сохраняет все значения в массиве f[], чтобы вы могли получить доступ к значениям по их именам, вот как выглядит содержимое этого массива:

$ cat tst.awk
BEGIN { FS="[,=[:space:]]"; OFS="=" }
/^-+$/ {
    for (i in f) printf "> f[%s]=%s\n", i, f[i]
    if ( f["ExtraStuff_ThirdBonusKey"] == 1 ) {
        print "AnotherField", f["AnotherField"]
    }
    print "----"
    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
----
> 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]=
----

Учитывая, что вы можете создать в любых условиях и / или распечатывать любые комбинации полей, которые вы хотите, в любом порядке ввода или вывода.

...