Проблема с функцией while в скрипте AWK

Edite su lista de fuentes de la siguiente manera:

#deb cdrom:[Debian GNU/Linux 2018.1 _Kali-rolling_ -
#Official Snapshot amd64 LIVE/INSTALL Binary 20180126-21:23]/ kali-last-snapshot contrib 
#main non-free

deb http://http.kali.org/kali kali-rolling main non-free contrib
# deb-src

O simplemente ejecute:

echo deb http://http.kali.org/kali kali-rolling main contrib non-free > /etc/apt/sources.list

Debe comentar la segunda y la tercera línea en su sources.list.

Véase El depósito rodante de Kali

1
19.06.2019, 08:38
2 ответа

Либо awkиспользуемый вами (GNU awkилиmawk)не сбрасывает данные, записанные в файл out1, когда вы его записываете, либо awkничего не читает из дескриптора файла, который вы держите открытым для записи. Это означает, что когда вы затем читаете из этого файла в блоке END, данные не считываются. Реализации BSD awk, похоже, не имеют этой проблемы, и ваш код работает, как и ожидалось, например, на. OpenBSD и macOS.

Решение простое: безоговорочно используйте close(out1)в блоке ENDперед чтением из него с помощью getline. В настоящее время вы закрываете его после чтения из него.

Кроме того, подумайте о том, чтобы быть немного более последовательным с вашими >и >>. Я считаю, что в этом коде вы можете использовать >.

4
27.01.2020, 23:17

Не ответ, так как @Kusalananda уже сказал вам, что не так, но давайте немного приведем ваш скрипт в порядок, чтобы сделать его читабельным и иметь немного меньше дублирования кода:

FNR == 1 {
    if ( NR != 1 ) {
        endfile()
    }
    avgLT = totFrames = denom = 0
    out1 = "analLT_" FILENAME
    out2 = "sumLT_" FILENAME
    out3 = "reportLT.txt"
    print "-> Input file is: " FILENAME > out3
    next
}

{
    avgLT += $4
    totFrames += $5
    ++denom
    printf "%10.4f %10.1f\n", $4, $5 > out1
}

END {
    endfile()
}

function endfile(       x, avgAvgLT, avgFrames, sd_avgLT,
                        semAvgLT, sd_totFrames, semTotFrames )
{
    if (avgLT == 0 && denom == 0 ) {
        x = "\nNO DATA POINTS IN INPUT => NO HYDROGEN BONDS DETECTED!"
        print x         > out1
        print x         > out2
        print x         > out3
    }
    else if (avgLT > 0) {
        avgAvgLT = avgLT / denom
        avgFrames = totFrames / denom

        close(out1)
        while ((getline < out1) > 0) {
            avgLTsq     += (($1 - avgAvgLT) ^ 2)
            avgFramessq += (($2 - avgFrames) ^ 2)
        }
        close(out1)

        printf "\n   Summary data for hbond lifetime analysis:\n\n"             > out2
        printf "   Summed Avg Lifetime:    %10.4f\n", avgLT                     > out2
        printf "   Average Lifetime:       %10.4f\n", avgAvgLT                  > out2
        printf "      Summed Frames:  %10.0f\n", totFrames                      > out2
        printf "      Average Frames:      %10.4f\n", avgFrames                 > out2

        printf "\n   Summary data for hbond lifetime analysis:\n\n"             > out3
        printf "   Summed Avg Lifetime:    %10.4f\n", avgLT                     > out3
        printf "   Average Lifetime:       %10.4f\n", avgAvgLT                  > out3
        printf "      Summed Frames:  %10.0f\n", totFrames                      > out3
        printf "      Average Frames:      %10.4f\n", avgFrames                 > out3

        if (denom == 1) {
            x = "   Single HBOND event, no SD or SEM calculation possible!"
            print x     > out2
            print ""    > out3
            print x     > out3
        }
        else if (denom > 1) {
            sd_avgLT = sqrt(avgLTsq / (denom - 1))
            semAvgLT = (sd_avgLT / (sqrt(denom)))
            sd_totFrames = sqrt(avgFramessq / (denom - 1))
            semTotFrames = (sd_totFrames / (sqrt(denom)))

            printf "\n   SD lifetime:            %10.4f\n", sd_avgLT            > out2
            printf "   SEM lifetime:           %10.4f\n", semAvgLT              > out2
            printf "      SD Frames:           %10.4f\n", sd_totFrames          > out2
            printf "      SEM Frames:          %10.4f\n\n", semTotFrames        > out2

            printf "\n   SD lifetime:            %10.4f\n", sd_avgLT            > out3
            printf "   SEM lifetime:           %10.4f\n", semAvgLT              > out3
            printf "      SD Frames:           %10.4f\n", sd_totFrames          > out3
            printf "      SEM Frames:          %10.4f\n\n", semTotFrames        > out3

            if (denom == 2) {
                x = "   2 Hydrogen bond events found! No proper SD or SEM!"
                print ""        > out2
                print x         > out2
                print x         > out3
        }
    }

    print "\n\n----------------------------------------\n"                      > out3

    close(out1)
    close(out2)
    close(out3)
}

Очевидно, что цикл while getline для out1 на самом деле не нужен, так как вы можете просто хранить данные в массиве вместо записи в out1 в основной части скрипта, например.:

FNR == 1 {
    if ( NR != 1 ) {
        endfile()
    }
    avgLT = totFrames =  denom = 0
    out1 = "analLT_" FILENAME
    out2 = "sumLT_" FILENAME
    out3 = "reportLT.txt"
    print "-> Input file is: " FILENAME > out3
    next
}

{
    avgLT += $4
    totFrames += $5
    ++denom
    fnr2avgLT[FNR] = avgLT
    fnr2totFrames[FNR] = totFrames
}

END {
    endfile()
}

function endfile(       i, x, avgAvgLT, avgFrames, sd_avgLT,
                        semAvgLT, sd_totFrames, semTotFrames )
{
    if (avgLT == 0 && denom == 0 ) {
        x = "\nNO DATA POINTS IN INPUT => NO HYDROGEN BONDS DETECTED!"
        print x         > out1
        print x         > out2
        print x         > out3
    }
    else if (avgLT > 0) {
        avgAvgLT = avgLT / denom
        avgFrames = totFrames / denom

        for (i=1; i<=FNR; i++) {
            avgLT = fnr2avgLT[i]
            totFrames = fnr2totFrames[i]
            printf "%10.4f %10.1f\n", avgLT, totFrames > out1

            avgLTsq     += ((avgLT - avgAvgLT) ^ 2)
            avgFramessq += ((totFrames - avgFrames) ^ 2)
        }

        printf "\n   Summary data for hbond lifetime analysis:\n\n"             > out2
        printf "   Summed Avg Lifetime:    %10.4f\n", avgLT                     > out2
        printf "   Average Lifetime:       %10.4f\n", avgAvgLT                  > out2
        printf "      Summed Frames:  %10.0f\n", totFrames                      > out2
        printf "      Average Frames:      %10.4f\n", avgFrames                 > out2

        printf "\n   Summary data for hbond lifetime analysis:\n\n"             > out3
        printf "   Summed Avg Lifetime:    %10.4f\n", avgLT                     > out3
        printf "   Average Lifetime:       %10.4f\n", avgAvgLT                  > out3
        printf "      Summed Frames:  %10.0f\n", totFrames                      > out3
        printf "      Average Frames:      %10.4f\n", avgFrames                 > out3

        if (denom == 1) {
            x = "   Single HBOND event, no SD or SEM calculation possible!"
            print x     > out2
            print ""    > out3
            print x     > out3
        }
        else if (denom > 1) {
            sd_avgLT = sqrt(avgLTsq / (denom - 1))
            semAvgLT = (sd_avgLT / (sqrt(denom)))
            sd_totFrames = sqrt(avgFramessq / (denom - 1))
            semTotFrames = (sd_totFrames / (sqrt(denom)))

            printf "\n   SD lifetime:            %10.4f\n", sd_avgLT            > out2
            printf "   SEM lifetime:           %10.4f\n", semAvgLT              > out2
            printf "      SD Frames:           %10.4f\n", sd_totFrames          > out2
            printf "      SEM Frames:          %10.4f\n\n", semTotFrames        > out2

            printf "\n   SD lifetime:            %10.4f\n", sd_avgLT            > out3
            printf "   SEM lifetime:           %10.4f\n", semAvgLT              > out3
            printf "      SD Frames:           %10.4f\n", sd_totFrames          > out3
            printf "      SEM Frames:          %10.4f\n\n", semTotFrames        > out3

            if (denom == 2) {
                x = "   2 Hydrogen bond events found! No proper SD or SEM!"
                print ""        > out2
                print x         > out2
                print x         > out3
        }
    }

    print "\n\n----------------------------------------\n"                      > out3

    close(out1)
    close(out2)
    close(out3)
}

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

1
27.01.2020, 23:17

Теги

Похожие вопросы