Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Shell 如何平均不同文件的值并将其保存到新文件中_Shell_Awk - Fatal编程技术网

Shell 如何平均不同文件的值并将其保存到新文件中

Shell 如何平均不同文件的值并将其保存到新文件中,shell,awk,Shell,Awk,我有大约140个包含数据的文件,我想用脚本处理这些文件 这些文件有两种类型的名称: sys-time-4-16-80-15-1-1.txt known-ratio-4-16-80-15-1-1.txt 最后两个数字不同的地方。倒数第二个数字是1,50,100,150,…,300,最后一个数字的范围是1,2,3,4,5…,10。下面是这些文件的一个示例 我想写一个包含3列的新文件,如下所示: 文件倒数第二列的第一列,即1,25,50。。。 第二列,每个sys time-..文件中第二列的平均值。

我有大约140个包含数据的文件,我想用脚本处理这些文件

这些文件有两种类型的名称:

  • sys-time-4-16-80-15-1-1.txt

  • known-ratio-4-16-80-15-1-1.txt

  • 最后两个数字不同的地方。倒数第二个数字是1,50,100,150,…,300,最后一个数字的范围是1,2,3,4,5…,10。下面是这些文件的一个示例

    我想写一个包含3列的新文件,如下所示:

    文件倒数第二列的第一列,即1,25,50。。。 第二列,每个
    sys time-..
    文件中第二列的平均值。 第三列,每个
    已知比率-…
    文件中第二列的平均值

    对于
    sys
    known
    文件的每对平均
    2nd列,结果可能有一行:

    1    mean-sys-1 mean-know-1
    1    mean-sys-2 mean-know-2
    .
    .
    1    mean-sys-10 mean-know-10
    50   mean-sys-1  mean-know-1
    50   mean-sys-2  mean-know-2
    .
    .
    50   mean-sys-10 mean-know-10
    100  mean-sys-1  mean-know-1
    100  mean-sys-2  mean-know-2
    .
    .
    100  mean-sys-10 mean-know-10
    ....
    ....
    300  mean-sys-10 mean-know-10
    
    其中每一行对应于最后两个数字相同的
    sys
    known
    文件。 此外,我想在第一列复制倒数第二个文件

    我知道如何使用
    awk
    计算文件第二列的平均值:

    awk '{ sum += $2; n++ } END { if (n > 0) print sum / n; }' sys-time-4-16-80-15-1-5.txt
    

    但我不知道如何迭代所有文件,并构建一个包含上述三列的结果文件

    我使用GNU Awk实现了简单的每个文件操作。这是未经检验的;请让我知道它是如何运行的。您可能需要查看
    printf()
    以获得漂亮的打印输出

    mapfile -t Files < <(find . -type f -name "*-4-16-80-15-*" |sort -t\- -k7,7 -k8,8)  #1
    gawk '
      BEGINFILE {n=split(FILENAME, f, "-"); type=f[1]; a[type]=0}                    #2
                {a[type] = ($2 + a[type] * c++) / c}                                 #3
      ENDFILE   {if(type=="sys") print f[n], a[sys], a[known]}                       #4
    ' "${Files[@]}"
    
  • 在每个文件的开头,清除任何现有的平均值,并将类型保存为“sys”或“known”

  • 在每一行上,计算

  • 在每个文件的末尾,检查文件类型。如果我们只是处理一个“sys”文件,那么打印文件名的最后一部分,然后是我们的平均值


  • 我使用GNU Awk实现了简单的每个文件操作。这是未经检验的;请让我知道它是如何运行的。您可能需要查看
    printf()
    以获得漂亮的打印输出

    mapfile -t Files < <(find . -type f -name "*-4-16-80-15-*" |sort -t\- -k7,7 -k8,8)  #1
    gawk '
      BEGINFILE {n=split(FILENAME, f, "-"); type=f[1]; a[type]=0}                    #2
                {a[type] = ($2 + a[type] * c++) / c}                                 #3
      ENDFILE   {if(type=="sys") print f[n], a[sys], a[known]}                       #4
    ' "${Files[@]}"
    
  • 在每个文件的开头,清除任何现有的平均值,并将类型保存为“sys”或“known”

  • 在每一行上,计算

  • 在每个文件的末尾,检查文件类型。如果我们只是处理一个“sys”文件,那么打印文件名的最后一部分,然后是我们的平均值


  • 下面是一个用于计算平均值的shell脚本(如果需要,您可以很容易地切换到awk;我更喜欢使用datamash来计算统计数据):

    #/垃圾箱/垃圾箱
    nums=$(mktemp)
    sysmeans=$(mktemp)
    knownmeans=$(mktemp)
    对于系统时间中的系统时间-*.txt
    做
    knownratio=$(echo-n“$systime”| sed-e's/sys time/known ratio/)
    echo“$systime”| sed-E的/*-([0-9]+)-[0-9]+\.txt/\1/'>>“$nums”
    datamash-W平均值2<“$systime”>>“$sysmeans”
    datamash-W平均值2<“$knownratio”>>“$knownmeans”
    完成
    粘贴“$nums”$sysmeans“$knownmeans”
    rm-f“$nums”$sys表示“$knownmeans”
    

    它创建三个临时文件,每列一个,在用每对文件的数据填充它们之后,每行一对,使用
    粘贴
    将它们组合起来,并将结果打印到标准输出。

    下面是一个用于计算平均值的shell脚本(如果需要,您可以轻松地切换到awk;我更喜欢datamash来计算统计数据):

    !/bin/sh
    nums=$(mktemp)
    sysmeans=$(mktemp)
    knownmeans=$(mktemp)
    对于系统时间中的系统时间-*.txt
    做
    knownratio=$(echo-n“$systime”| sed-e's/sys time/known ratio/)
    echo“$systime”| sed-E的/*-([0-9]+)-[0-9]+\.txt/\1/'>>“$nums”
    datamash-W平均值2<“$systime”>>“$sysmeans”
    datamash-W平均值2<“$knownratio”>>“$knownmeans”
    完成
    粘贴“$nums”$sysmeans“$knownmeans”
    rm-f“$nums”$sys表示“$knownmeans”
    

    它创建了三个临时文件,每列一个,在用每对文件中的数据填充它们之后,每行一对,使用
    粘贴
    将它们组合起来,并将结果打印到标准输出。

    @vintnes您是对的。链接的名称中有倒数第二个值1、50、100、150、200。上面的示例仅此而已一个简短的文件示例。我想在链接的所有文件中运行脚本。@vintnes你说得对。链接名称中倒数第二个值为1、50、100、150、200。上面的示例只是一个简短的文件示例。我想在链接的所有文件中运行脚本。谢谢。我不知道
    datamash
    。可以吗询问您如何更改脚本以使用两个不同文件夹中的文件(名称相同)。@user1993416使用
    basename
    命令将非常有用。谢谢。我不知道
    datamash
    。我可以问您如何更改脚本以使用文件(名称相同)从两个不同的文件夹@user1993416使用
    basename
    命令将非常有用。