如何使用 awk 一次解析 500 个文件来查找文件中值的标准差?

如何使用 awk 一次解析 500 个文件来查找文件中值的标准差?

我有 500 个文件,每个文件有一列值,我需要查找其标准差。我已经弄清楚了这么多:

awk '{sum+=$5; array[NR]=$5} END {for(x=1;x<=NR;x++){sumsq+=((array[x]-(sum/NR))**2);}print sqrt(sumsq/NR)}' SL9_700.00001.bt

但我不知道如何立即为所有 SL9_700.0* 文件复制此内容。

答案1

如果您的脚本对 1 个文件执行了您想要的操作,那么使用 GNU awk for ENDFILE 您只需调整它以使用 ENDFILE 而不是 END,使用 FNR 而不是 NR,并在为每个文件使用变量后重置变量:

awk '{sum+=$5; array[FNR]=$5} ENDFILE {for(x=1;x<=FNR;x++){sumsq+=((array[x]-(sum/FNR))**2);}print sqrt(sumsq/FNR); sum=sumsq=0}' SL9_700.0*

或者更清晰地:

awk '
    {
        sum += $5
        array[FNR] = $5
    }

    ENDFILE {
        for (x = 1; x <= FNR; x++) {
            sumsq += ((array[x] - (sum / FNR)) ^ 2)
        }
        print sqrt(sumsq / FNR)
        sum = sumsq = 0
    }
' SL9_700.0*

您可能需要在 ENDFILE 部分中添加 FNR 为 0 的测试,并在这种情况下执行某些操作以避免空输入文件出现被零除错误(对于原始脚本中 END 部分中的 NR 也是如此),例如:

awk '
    {
        sum += $5
        array[FNR] = $5
    }

    ENDFILE {
        if ( FNR == 0 ) {
            print 0
        }
        else {
            for (x = 1; x <= FNR; x++) {
                sumsq += ((array[x] - (sum / FNR)) ^ 2)
            }
            print sqrt(sumsq / FNR)
            sum = sumsq = 0
        }
    }
' SL9_700.0*

如果您希望在每个输出值之前打印文件名,请将每个更改printprint FILENAME,

相关内容