我怎样才能在 awk 中做到这一点?我有几个文件,其中有两列,第一列中的值相同。如何逐行平均第二列中的值?

蚂蚁

我是一个缺乏经验的 Awk 用户,但我知道 Awk 是处理许多文件的有效选择。如果有人能指出我正确的方向,我将不胜感激。

我有一个名为parent. 里面有更多名为1, 2, 3, 4, .... 在每个目录中都有一个名为angles. 里面angles是一个名为 的文件angle_A_B_C.dat,如下所示。

parent
  1
     angles
       angle_A_B_C.dat
  2
     angles
       angle_A_B_C.dat
  3
     angles
       angle_A_B_C.dat
  4
     angles
       angle_A_B_C.dat
  ...

这些文件angle_A_B_C.dat都具有相同的行数 (91) 和相同的第一列。只有第二列中的值是不同的。以下是一个angle_A_B_C.dat文件的示例:

# Deg[°]         Angle[A ,B ,C ] 
     1.000        0.0000000000
     3.000        0.0000000000
     5.000        0.0000000000
     7.000        0.0000000000
     9.000        0.0000000000
    11.000        0.0000000000
    13.000        0.0000000000
    15.000        0.0000000000
    17.000        0.0000000000
    19.000        0.0000000000
    21.000        0.0000000000
    23.000        0.0000000000
    25.000        0.0000000000
    27.000        0.0000000000
    29.000        0.0000000000
    31.000        0.0000000000
    33.000        0.0000000000
    35.000        0.0000000000
    37.000        0.0000000000
    39.000        0.0000000000
    41.000        0.0000000000
    43.000        0.0000000000
    45.000        0.0000000000
    47.000        0.0000000000
    49.000        0.0000000000
    51.000        0.0000000000
    53.000        0.0000000000
    55.000        0.0000000000
    57.000        0.0000000000
    59.000        0.0000000000
    61.000        0.0000000000
    63.000        0.0000000000
    65.000        0.0000000000
    67.000        1.0309278351
    69.000        1.0309278351
    71.000        2.0618556701
    73.000        1.0309278351
    75.000        2.0618556701
    77.000        0.0000000000
    79.000        0.0000000000
    81.000        4.1237113402
    83.000        2.0618556701
    85.000        4.1237113402
    87.000        2.0618556701
    89.000        2.0618556701
    91.000        5.1546391753
    93.000        3.0927835052
    95.000        1.0309278351
    97.000        3.0927835052
    99.000        1.0309278351
   101.000        2.0618556701
   103.000        9.2783505155
   105.000        7.2164948454
   107.000        4.1237113402
   109.000        5.1546391753
   111.000        5.1546391753
   113.000        3.0927835052
   115.000        2.0618556701
   117.000        9.2783505155
   119.000        0.0000000000
   121.000        3.0927835052
   123.000        3.0927835052
   125.000        2.0618556701
   127.000        0.0000000000
   129.000        1.0309278351
   131.000        1.0309278351
   133.000        2.0618556701
   135.000        1.0309278351
   137.000        0.0000000000
   139.000        1.0309278351
   141.000        0.0000000000
   143.000        0.0000000000
   145.000        1.0309278351
   147.000        0.0000000000
   149.000        0.0000000000
   151.000        1.0309278351
   153.000        0.0000000000
   155.000        0.0000000000
   157.000        1.0309278351
   159.000        0.0000000000
   161.000        0.0000000000
   163.000        0.0000000000
   165.000        0.0000000000
   167.000        0.0000000000
   169.000        0.0000000000
   171.000        0.0000000000
   173.000        0.0000000000
   175.000        0.0000000000
   177.000        0.0000000000
   179.000        0.0000000000

我想生成一个名为的文件anglesSummary.txt,其中第一列与上面示例中的所有angle_A_B_C.dat文件相同,并且第二列的每一行是所有其他文件中同一行的平均值。

我大致记得如何取位于不同目录中不同文件中的整个列的平均值,但不知道如何一次只处理一行。这可能吗?

这是我现在的位置;问号显示我认为我被困在哪里。

cd parent
find . -name angle_A_B_C.dat -exec grep "Angle[A ,B ,C ]" {} + > anglesSummary.txt
my_output="$(awk '{ total += ??? } END { print total/NR }' anglesSummary.txt)"
echo "Average: $my_output" >> anglesSummary.txt

更新(回应 markp-fuso 评论)

我想要什么(请参阅第 1 列值为 15.000 的行的注释):

# Deg[°]         Angle[A ,B ,C ] 
     1.000        0.0000000000
     3.000        0.0000000000
     5.000        0.0000000000
     7.000        0.0000000000
     9.000        0.0000000000
    11.000        0.0000000000
    13.000        0.0000000000
    15.000        1.2222220000 # <--Each row in column 2 is the average of the value in the corresponding row, column 2 in all files. So this particular value (1.222222) is the average of the values in all files where the column 1 value is 15.000.
    17.000        0.0000000000
    19.000        0.0000000000
    21.000        0.0000000000
    23.000        0.0000000000
    25.000        0.0000000000
    27.000        0.0000000000
    29.000        0.0000000000
    31.000        0.0000000000
    33.000        0.0000000000
    35.000        0.0000000000
    ... (truncated)

我目前从我的代码中得到的是每个 angle_A_B_C.dat 文件中第 2 列的平均值。

如果这仍然不清楚,请随时说出来,我会重写它。谢谢你。

markp扶桑

样本输入:

$ head */*/angle*
==> 1/angles/angle_A_B_C.dat <==
# Deg[°]         Angle[A ,B ,C ]
     1.000        0.3450000000
     3.000        0.4560000000
     5.000        0.7890000000
     7.000        10.0000000000
     9.000        20.0000000000
    11.000        30.0000000000
    13.000        40.0000000000

==> 2/angles/angle_A_B_C.dat <==
# Deg[°]         Angle[A ,B ,C ]
     1.000        7.3450000000
     3.000        8.4560000000
     5.000        9.7890000000
     7.000        17.0000000000
     9.000        27.0000000000
    11.000        37.0000000000
    13.000        47.0000000000

==> 3/angles/angle_A_B_C.dat <==
# Deg[°]         Angle[A ,B ,C ]
     1.000        0.9876000000
     3.000        0.5432000000
     5.000        0.2344560000
     7.000        3.0000000000
     9.000        4.0000000000
    11.000        5.0000000000
    13.000        6.0000000000

一个GNU awk想法:

find . -name angle_A_B_C.dat -type f -exec awk '
NR==1   { printf "%s\t%s\n","# Deg[°]", "Angle[A ,B ,C ]" }   # 1st record of 1st file => print header
FNR==1  { filecount++; next }                                 # 1st record of each new file => increment file counter; skip to next input line
NF==2   { sums[$1]+=$2 }                                      # sum up angles, use 1st column as array index
END     { if (filecount>0) {                                  # eliminate "divide by zero" error if no files found
              PROCINFO["sorted_in"]="@ind_num_asc"            # sort array by numeric index in ascending order
              for (i in sums)                                 # loop through array indices, printing index and average
                  printf "%.3f\t%.10f\n", i, sums[i]/filecount
          }
        }
' {} +

笔记:

  • GNU awk需要PROCINFO["sorted_in"]允许以# Deg[°]升序生成输出(否则输出可以通过管道传输sort以确保所需的顺序)

假设输入行已经排序:

find . -name angle_A_B_C.dat -type f -exec awk '
NR==1   { printf "%s\t%s\n","# Deg[°]", "Angle[A ,B ,C ]" }
FNR==1  { filecount++; next }
NF==2   { col1[FNR]=$1;  sums[FNR]+=$2 }
END     { if (filecount>0)
              for (i=2;i<=FNR;i++)
                  printf "%.3f\t%.10f\n", col1[i], sums[i]/filecount
        }
' {} +

笔记:

  • 应该在所有awk版本中运行(即不需要GNU awk
  • 基于 jhnc 的评论(如果 jhnc 想发布单独的答案,我可以删除这部分答案)

这两个生成:

# Deg[°]         Angle[A ,B ,C ]
1.000   2.8925333333
3.000   3.1517333333
5.000   3.6041520000
7.000   10.0000000000
9.000   17.0000000000
11.000  24.0000000000
13.000  31.0000000000

笔记:

  • printf通过修改格式字符串,可以根据 OP 的喜好调整输出格式

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章